From 420672dacb403aebffb670ff9664cb2900cfe7e9 Mon Sep 17 00:00:00 2001 From: llea <llea> Date: Thu, 2 Jun 2005 20:50:46 +0000 Subject: [PATCH] Changes about audiodriversportaudio --- src/Makefile | 4 +- src/audio/audiodriversportaudio.cpp | 87 +- src/audio/audiodriversportaudio.h | 6 +- src/audio/audiortp.cpp | 19 +- src/audio/codecDescriptor.cpp | 8 +- src/audio/codecDescriptor.h | 1 + src/audio/dtmfgenerator.cpp | 3 +- src/audio/portaudio/docs/index.html | 60 ++ src/audio/portaudio/docs/latency.html | 192 ++++ src/audio/portaudio/docs/pa_impl_guide.html | 197 ++++ .../portaudio/docs/pa_impl_startstop.html | 190 ++++ src/audio/portaudio/docs/pa_tut_asio.html | 55 + src/audio/portaudio/docs/pa_tut_callback.html | 91 ++ src/audio/portaudio/docs/pa_tut_devs.html | 65 ++ src/audio/portaudio/docs/pa_tut_explore.html | 42 + src/audio/portaudio/docs/pa_tut_init.html | 43 + src/audio/portaudio/docs/pa_tut_mac.html | 41 + src/audio/portaudio/docs/pa_tut_mac_osx.html | 46 + src/audio/portaudio/docs/pa_tut_open.html | 52 + src/audio/portaudio/docs/pa_tut_oss.html | 46 + src/audio/portaudio/docs/pa_tut_over.html | 92 ++ src/audio/portaudio/docs/pa_tut_pc.html | 78 ++ src/audio/portaudio/docs/pa_tut_run.html | 56 + src/audio/portaudio/docs/pa_tut_rw.html | 79 ++ src/audio/portaudio/docs/pa_tut_term.html | 47 + src/audio/portaudio/docs/pa_tut_util.html | 55 + src/audio/portaudio/docs/pa_tutorial.html | 46 + src/audio/portaudio/docs/portaudio_h.txt | 425 ++++++++ .../portaudio/docs/portaudio_icmc2001.pdf | Bin 0 -> 50968 bytes src/audio/portaudio/docs/proposals.html | 36 + src/audio/portaudio/docs/releases.html | 339 ++++++ src/audio/tonegenerator.cpp | 82 +- src/audio/tonegenerator.h | 7 +- src/global.h | 2 +- src/gui/qt/configurationpanel.ui | 259 ++--- src/gui/qt/configurationpanel.ui.h | 6 +- src/gui/qt/configurationpanelui.cpp | 987 ++++++++---------- src/gui/qt/configurationpanelui.h | 17 +- src/gui/qt/qtGUImainwindow.cpp | 29 +- src/gui/qt/url_inputui.cpp | 2 +- src/gui/qt/url_inputui.h | 2 +- src/manager.cpp | 61 +- src/sipvoiplink.cpp | 6 +- 43 files changed, 3126 insertions(+), 835 deletions(-) create mode 100644 src/audio/portaudio/docs/index.html create mode 100644 src/audio/portaudio/docs/latency.html create mode 100644 src/audio/portaudio/docs/pa_impl_guide.html create mode 100644 src/audio/portaudio/docs/pa_impl_startstop.html create mode 100644 src/audio/portaudio/docs/pa_tut_asio.html create mode 100644 src/audio/portaudio/docs/pa_tut_callback.html create mode 100644 src/audio/portaudio/docs/pa_tut_devs.html create mode 100644 src/audio/portaudio/docs/pa_tut_explore.html create mode 100644 src/audio/portaudio/docs/pa_tut_init.html create mode 100644 src/audio/portaudio/docs/pa_tut_mac.html create mode 100644 src/audio/portaudio/docs/pa_tut_mac_osx.html create mode 100644 src/audio/portaudio/docs/pa_tut_open.html create mode 100644 src/audio/portaudio/docs/pa_tut_oss.html create mode 100644 src/audio/portaudio/docs/pa_tut_over.html create mode 100644 src/audio/portaudio/docs/pa_tut_pc.html create mode 100644 src/audio/portaudio/docs/pa_tut_run.html create mode 100644 src/audio/portaudio/docs/pa_tut_rw.html create mode 100644 src/audio/portaudio/docs/pa_tut_term.html create mode 100644 src/audio/portaudio/docs/pa_tut_util.html create mode 100644 src/audio/portaudio/docs/pa_tutorial.html create mode 100644 src/audio/portaudio/docs/portaudio_h.txt create mode 100644 src/audio/portaudio/docs/portaudio_icmc2001.pdf create mode 100644 src/audio/portaudio/docs/proposals.html create mode 100644 src/audio/portaudio/docs/releases.html diff --git a/src/Makefile b/src/Makefile index 4151515f31..954ef5b806 100644 --- a/src/Makefile +++ b/src/Makefile @@ -101,8 +101,8 @@ OBJS = \ udp.o -#start: check prereq all -start:check all +start: check prereq all +#start:check all check: ifeq ($(CONFIGURE_CONF),../configure.conf) diff --git a/src/audio/audiodriversportaudio.cpp b/src/audio/audiodriversportaudio.cpp index f03effe58f..1c1e8d2ddb 100644 --- a/src/audio/audiodriversportaudio.cpp +++ b/src/audio/audiodriversportaudio.cpp @@ -29,10 +29,10 @@ AudioDriversPortAudio::AudioDriversPortAudio (Manager* manager) { _manager = manager; - mydata.dataToAddRem = 0; - mydata.dataFilled = 0; + mydata.urg_remain = 0; mydata.dataIn = NULL; mydata.dataOut = NULL; + mydata.urg_data = NULL; this->initDevice(); } @@ -76,13 +76,13 @@ bool AudioDriversPortAudio::openDevice (void) { int err = Pa_OpenDefaultStream ( &_stream, /* passes back stream pointer */ - 1, /* mono input */ - 1, /* mono output */ + 2, /* input channel */ + 2, /* output channel */ paFloat32, /* 32 bit float output */ SAMPLING_RATE, /* sample rate */ FRAME_PER_BUFFER, /* frames per buffer */ audioCallback, /* specify our custom callback */ - &mydata); /* pass our data through to callback */ + &mydata); /* pass our data through to callback */ if (err != paNoError) { _debug ("PortAudio error in Pa_OpenDefaultStream: %s\n", Pa_GetErrorText(err)); @@ -95,11 +95,15 @@ AudioDriversPortAudio::openDevice (void) { int AudioDriversPortAudio::readBuffer (void *ptr, int bytes) { + (void) ptr; + (void) bytes; return 1; } int AudioDriversPortAudio::writeBuffer (void *ptr, int len) { + (void) ptr; + (void) len; return 1; } @@ -107,11 +111,13 @@ int AudioDriversPortAudio::startStream(void) { int err; - - err = Pa_StartStream (_stream); - if( err != paNoError ) { - _debug ("PortAudio error in Pa_StartStream: %s\n", Pa_GetErrorText(err)); - return 0; + if (!Pa_IsStreamActive(_stream)) { + err = Pa_StartStream (_stream); + if( err != paNoError ) { + _debug ("PortAudio error in Pa_StartStream: %s\n", + Pa_GetErrorText(err)); + return 0; + } } return 1; @@ -122,11 +128,15 @@ AudioDriversPortAudio::stopStream(void) { int err; - err = Pa_StopStream (_stream); - if( err != paNoError ) { - _debug ("PortAudio error in Pa_StopStream: %s\n", Pa_GetErrorText(err)); - return 0; + if (!Pa_IsStreamStopped(_stream)) { + err = Pa_StopStream (_stream); + if( err != paNoError ) { + _debug ("PortAudio error in Pa_StopStream: %s\n", + Pa_GetErrorText(err)); + return 0; + } } + return 1; } @@ -168,52 +178,31 @@ AudioDriversPortAudio::audioCallback (const void *inputBuffer, float32 *out = (float32 *) outputBuffer; paData* data = (paData*) userData; - unsigned int i; + int i; + int it; -#if 1 /* Fill output buffer */ - int j = data->dataToAddRem; - int k = data->dataFilled; - for (i = 0; i < framesPerBuffer; i++) { - if (j > 0 && k < j) { - *out++ = data->dataToAdd[i+k]; + for (i = 0; i < (int)framesPerBuffer; i++) { + it = 2*i; + if (data->urg_remain - i > 0) { + out[it] = out[it+1] = data->urg_ptr[i]; } else { - *out++ = data->dataOut[i]; + out[it] = out[it+1] = data->dataOut[i]; } - } - k += framesPerBuffer; - if (k >= j) { - data->dataFilled = 0; + } + + if ((data->urg_remain -i) > 0) { + data->urg_ptr +=i; + data->urg_remain-= i; } else { - data->dataFilled = k; + data->urg_remain = 0; } -#endif /* Read input buffer */ if (data->dataIn != NULL) { - memcpy (data->dataIn, in, sizeof(float32) * framesPerBuffer); - } - -#if 0 - int j = data->dataToAddRem; - /* Fill output buffer */ - for (i = 0; i < framesPerBuffer; i++) { - if (j > 0 && j >= i) { - *out++ = data->dataToAdd[j-i]; - } else { - *out++ = data->dataOut[i]; - } - } - - j = j - i; - if (j > 0) { - data->dataToAddRem = j; - } else { - data->dataToAddRem = 0; - // cout << "please FREE data->dataToAdd now!!!" << endl; + memcpy (data->dataIn, in, 2*sizeof(float32) * framesPerBuffer); } -#endif return paContinue; } #endif // defined(AUDIO_PORTAUDIO) diff --git a/src/audio/audiodriversportaudio.h b/src/audio/audiodriversportaudio.h index 4e9d1582a8..206278afdd 100644 --- a/src/audio/audiodriversportaudio.h +++ b/src/audio/audiodriversportaudio.h @@ -34,9 +34,9 @@ public: struct paData { float32 *dataIn; // From mic float32 *dataOut; // To spk - float32 *dataToAdd; // To spk - int dataToAddRem; - int dataFilled; + float32 *urg_data; // data in priority + float32 *urg_ptr; + int urg_remain; // data remained in urg_data }; paData mydata; diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp index a4c440e0ab..c32564b4ee 100644 --- a/src/audio/audiortp.cpp +++ b/src/audio/audiortp.cpp @@ -150,6 +150,7 @@ AudioRtpRTX::run (void) { int countTime = 0; int16 *data_for_speakers = NULL; float32 *data_for_speakers_float = NULL; + float32 *data_for_speakers_float_tmp = NULL; data_from_mic = new float32[1024]; data_from_mic_tmp = new float32[1024]; @@ -236,6 +237,7 @@ AudioRtpRTX::run (void) { _manager->getAudioDriver()->mydata.dataIn = data_mute; } + // Control volume for micro for (int j = 0; j < size; j++) { data_from_mic_tmp[j] = data_from_mic[j] * _manager->getMicroVolume()/100; @@ -284,9 +286,15 @@ AudioRtpRTX::run (void) { data_for_speakers_float = new float32[expandedSize]; ac->int16ToFloat32 (data_for_speakers, data_for_speakers_float, expandedSize); - + + // control volume for speakers + data_for_speakers_float_tmp = new float32[expandedSize]; + for (int j = 0; j < expandedSize; j++) { + data_for_speakers_float_tmp[j] = data_for_speakers_float[j] * + _manager->getSpkrVolume()/100; + } // Set decoded data to sound device - _manager->getAudioDriver()->mydata.dataOut = data_for_speakers_float; + _manager->getAudioDriver()->mydata.dataOut =data_for_speakers_float_tmp; // Notify (with a bip) an incoming call when there is already a call countTime += time->getSecond(); @@ -304,14 +312,13 @@ AudioRtpRTX::run (void) { Thread::sleep(TimerPort::getTimer()); TimerPort::incTimer(frameSize); // 'frameSize' ms - if (!_manager->getAudioDriver()->isStreamActive()) { - _manager->getAudioDriver()->mydata.dataToAddRem = 0; - _manager->getAudioDriver()->startStream(); - } + // Start PortAudio + _manager->getAudioDriver()->startStream(); } delete[] data_for_speakers; delete[] data_for_speakers_float; + delete[] data_for_speakers_float_tmp; delete[] data_from_mic; delete[] data_from_mic_int16; delete[] data_from_mic_tmp; diff --git a/src/audio/codecDescriptor.cpp b/src/audio/codecDescriptor.cpp index 7cc255b792..60f7f13d5a 100644 --- a/src/audio/codecDescriptor.cpp +++ b/src/audio/codecDescriptor.cpp @@ -28,7 +28,13 @@ CodecDescriptor::CodecDescriptor (int payload) { _payload = payload; - _codecName = ""; + _codecName = rtpmapPayload(_payload); +} + +CodecDescriptor::CodecDescriptor (const string& name) +{ + _codecName = name; + _payload = matchPayloadCodec(name); } CodecDescriptor::CodecDescriptor (int payload, const string& name) diff --git a/src/audio/codecDescriptor.h b/src/audio/codecDescriptor.h index e651f3727c..81370da8c3 100644 --- a/src/audio/codecDescriptor.h +++ b/src/audio/codecDescriptor.h @@ -45,6 +45,7 @@ class CodecDescriptor { public: CodecDescriptor (int payload); + CodecDescriptor (const string& name); CodecDescriptor (int payload, const string& name); ~CodecDescriptor (void); diff --git a/src/audio/dtmfgenerator.cpp b/src/audio/dtmfgenerator.cpp index 559d6b6daa..169bfc9e46 100644 --- a/src/audio/dtmfgenerator.cpp +++ b/src/audio/dtmfgenerator.cpp @@ -172,8 +172,7 @@ float32* DTMFGenerator::generateSample(unsigned char code) throw (DTMFException) return 0; } - generateSin(tones[code].higher, tones[code].lower, - SAMPLING_RATE, ptr); + generateSin(tones[code].higher, tones[code].lower, ptr); return ptr; // } catch(...) { diff --git a/src/audio/portaudio/docs/index.html b/src/audio/portaudio/docs/index.html new file mode 100644 index 0000000000..7d9b248d30 --- /dev/null +++ b/src/audio/portaudio/docs/index.html @@ -0,0 +1,60 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="PortAudio Docs, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Docs</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Documentation</h1></center> +</td> +</tr> +</table></center> + +<p>Copyright 2000 Phil Burk and Ross Bencina +<br> +<h3> +<a href="portaudio_h.txt">API Reference</a></h3> + +<blockquote>The Application Programmer Interface is documented in "portaudio.h".</blockquote> + +<h3> +<a href="pa_tutorial.html">Tutorial</a></h3> + +<blockquote>Describes how to write audio programs using the PortAudio API.</blockquote> + +<h3> +<a href="pa_impl_guide.html">Implementation Guide</a></h3> + +<blockquote>Describes how to write an implementation of PortAudio for a +new computer platform.</blockquote> + +<h3> +<a href="portaudio_icmc2001.pdf">Paper Presented at ICMC2001</a> (PDF)</h3> + +<blockquote>Describes the PortAudio API and discusses implementation issues. +Written July 2001.</blockquote> + +<h3> +<a href="latency.html">Improving Latency</a></h3> + +<blockquote>How to tune your computer to achieve the lowest possible audio +delay.</blockquote> + +<h3> +<a href="proposals.html">Proposed Changes</a></h3> + +<blockquote>Describes API changes being considered by the developer community. +Feedback welcome.</blockquote> +<a href="http://www.portaudio.com/">Return to PortAudio Home Page</a> +</body> +</html> diff --git a/src/audio/portaudio/docs/latency.html b/src/audio/portaudio/docs/latency.html new file mode 100644 index 0000000000..87f1d1222b --- /dev/null +++ b/src/audio/portaudio/docs/latency.html @@ -0,0 +1,192 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Internal docs. How a stream is started or stopped."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Implementation - Start/Stop</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +<a href="http://www.portaudio.com">PortAudio</a> Latency</h1></center> +</td> +</tr> +</table></center> + +<p>This page discusses the issues of audio latency for <a href="http://www.portaudio.com">PortAudio</a> +. It offers suggestions on how to lower latency to improve the responsiveness +of applications. +<blockquote><b><a href="#what">What is Latency?</a></b> +<br><b><a href="#portaudio">PortAudio and Latency</a></b> +<br><b><a href="#macintosh">Macintosh</a></b> +<br><b><a href="#unix">Unix</a></b> +<br><b><a href="#windows">WIndows</a></b></blockquote> +By Phil Burk, Copyright 2002 Phil Burk and Ross Bencina +<h2> +<a NAME="what"></a>What is Latency?</h2> +Latency is basically longest time that you have to wait before you obtain +a desired result. For digital audio output it is the time between making +a sound in software and finally hearing it. +<p>Consider the example of pressing a key on the ASCII keyboard to play +a note. There are several stages in this process which each contribute +their own latency. First the operating system must respond to the keypress. +Then the audio signal generated must work its way through the PortAudio +buffers. Then it must work its way through the audio card hardware. Then +it must go through the audio amplifier which is very quick and then travel +through the air. Sound travels at abous one foot per millisecond through +air so placing speakers across the room can add 5-20 msec of delay. +<p>The reverse process occurs when recording or responding to audio input. +If you are processing audio, for example if you implement a software guitar +fuzz box, then you have both the audio input and audio output latencies +added together. +<p>The audio buffers are used to prevent glitches in the audio stream. +The user software writes audio into the output buffers. That audio is read +by the low level audio driver or by DMA and sent to the DAC. If the computer +gets busy doing something like reading the disk or redrawing the screen, +then it may not have time to fill the audio buffer. The audio hardware +then runs out of audio data, which causes a glitch. By using a large enough +buffer we can ensure that there is always enough audio data for the audio +hardware to play. But if the buffer is too large then the latency is high +and the system feels sluggish. If you play notes on the keyboard then the +"instrument" will feel unresponsive. So you want the buffers to be as small +as possible without glitching. +<h2> +<a NAME="portaudio"></a>PortAudio and Latency</h2> +The only delay that PortAudio can control is the total length of its buffers. +The Pa_OpenStream() call takes two parameters: numBuffers and framesPerBuffer. +The latency is also affected by the sample rate which we will call framesPerSecond. +A frame is a set of samples that occur simultaneously. For a stereo stream, +a frame is two samples. +<p>The latency in milliseconds due to this buffering is: +<blockquote><tt>latency_msec = 1000 * numBuffers * framesPerBuffer / framesPerSecond</tt></blockquote> +This is not the total latency, as we have seen, but it is the part we can +control. +<p>If you call Pa_OpenStream() with numBuffers equal to zero, then PortAudio +will select a conservative number that will prevent audio glitches. If +you still get glitches, then you can pass a larger value for numBuffers +until the glitching stops. if you try to pass a numBuffers value that is +too small, then PortAudio will use its own idea of the minimum value. +<p>PortAudio decides on the minimum number of buffers in a conservative +way based on the frameRate, operating system and other variables. You can +query the value that PortAudio will use by calling: +<blockquote><tt>int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate +);</tt></blockquote> +On some systems you can override the PortAudio minimum if you know your +system can handle a lower value. You do this by setting an environment +variable called PA_MIN_LATENCY_MSEC which is read by PortAudio when it +starts up. This is supported on the PortAudio implementations for Windows +MME, Windows DirectSound, and Unix OSS. +<h2> +<a NAME="macintosh"></a>Macintosh</h2> +The best thing you can do to improve latency on Mac OS 8 and 9 is to turn +off Virtual Memory. PortAudio V18 will detect that Virtual Memory is turned +off and use a very low latency. +<p>For Mac OS X the latency is very low because Apple Core Audio is so +well written. You can set the PA_MIN_LATENCY_MSEC variable using: +<blockquote><tt>setenv PA_MIN_LATENCY_MSEC 4</tt></blockquote> + +<h2> +<a NAME="unix"></a>Unix</h2> +PortAudio under Unix currently uses a backgroud thread that reads and writes +to OSS. This gives you decent but not great latency. But if you raise the +priority of the background thread to a very priority then you can get under +10 milliseconds latency. In order to raise your priority you must run the +PortAudio program as root! You must also set PA_MIN_LATENCY_MSEC using +the appropriate command for your shell. +<h2> +<a NAME="windows"></a>Windows</h2> +Latency under Windows is a complex issue because of all the alternative +operating system versions and device drivers. I have seen latency range +from 8 milliseconds to 400 milliseconds. The worst case is when using Windows +NT. Windows 98 is a little better, and Windows XP can be quite good if +properly tuned. +<p>The underlying audio API also makes a lot of difference. If the audio +device has its own DirectSound driver then DirectSound can often provide +better latency than WMME. But if a real DirectSound driver is not available +for your device then it is emulated using WMME and the latency can be very +high. That's where I saw the 400 millisecond latency. The ASIO implementation +is generally very good and will give the lowest latency if available. +<p>You can set the PA_MIN_LATENCY_MSEC variable to 50, for example, by +entering in MS-DOS: +<blockquote><tt>set PA_MIN_LATENCY_MSEC=50</tt></blockquote> +If you enter this in a DOS window then you must run the PortAudio program +from that same window for the variable to have an effect. You can add that +line to your C:\AUTOEXEC.BAT file and reboot if you want it to affect any +PortAudio based program. +<p>For Windows XP, you can set environment variables as follows: +<ol> +<li> +Select "Control Panel" from the "Start Menu".</li> + +<li> +Launch the "System" Control Panel</li> + +<li> +Click on the "Advanced" tab.</li> + +<li> +Click on the "Environment Variables" button.</li> + +<li> +Click "New" button under User Variables.</li> + +<li> +Enter PA_MIN_LATENCY_MSEC for the name and some optimistic number for the +value.</li> + +<li> +Click OK, OK, OK.</li> +</ol> + +<h3> +Improving Latency on Windows</h3> +There are several steps you can take to improve latency under windows. +<ol> +<li> +Avoid reading or writng to disk when doing audio.</li> + +<li> +Turn off all automated background tasks such as email clients, virus scanners, +backup programs, FTP servers, web servers, etc. when doing audio.</li> + +<li> +Disconnect from the network to prevent network traffic from interrupting +your CPU.</li> +</ol> +<b>Important: </b>Windows XP users can also tune the OS to favor background +tasks, such as audio, over foreground tasks, such as word processing. I +lowered my latency from 40 to 10 milliseconds using this simple technique. +<ol> +<li> +Select "Control Panel" from the "Start Menu".</li> + +<li> +Launch the "System" Control Panel</li> + +<li> +Click on the "Advanced" tab.</li> + +<li> +Click on the "Settings" button in the Performance area.</li> + +<li> +Click on the "Advanced" tab.</li> + +<li> +Select "Background services" in the Processor Scheduling area.</li> + +<li> +Click OK, OK.</li> +</ol> +Please let us know if you have others sugestions for lowering latency. +<br> +<br> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_impl_guide.html b/src/audio/portaudio/docs/pa_impl_guide.html new file mode 100644 index 0000000000..50abc30454 --- /dev/null +++ b/src/audio/portaudio/docs/pa_impl_guide.html @@ -0,0 +1,197 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Internal docs. How a stream is started or stopped."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Implementation - Start/Stop</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +<a href="http://www.portaudio.com">PortAudio</a> Implementation Guide</h1></center> +</td> +</tr> +</table></center> + +<p>This document describes how to implement the PortAudio API on a new +computer platform. Implementing PortAudio on a new platform, makes it possible +to port many existing audio applications to that platform. +<p>By Phil Burk +<br>Copyright 2000 Phil Burk and Ross Bencina +<p>Note that the license says: <b>"Any person wishing to distribute modifications +to the Software is requested to send the modifications to the original +developer so that they can be incorporated into the canonical version."</b>. +So when you have finished a new implementation, please send it back to +us at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>" +so that we can make it available for other users. Thank you! +<h2> +Download the Latest PortAudio Implementation</h2> +Always start with the latest implementation available at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>". +Look for the nightly snapshot under the CVS section. +<h2> +Select an Existing Implementation as a Basis</h2> +The fastest way to get started is to take an existing implementation and +translate it for your new platform. Choose an implementation whose architecture +is as close as possible to your target. +<ul> +<li> +DirectSound Implementation - pa_win_ds - Uses a timer callback for the +background "thread". Polls a circular buffer and writes blocks of data +to keep it full.</li> + +<li> +Windows MME - pa_win_wmme - Spawns an actual Win32 thread. Writes blocks +of data to the HW device and waits for events that signal buffer completion.</li> + +<li> +Linux OSS - pa_linux - Spawns a real thread that writes to the "/dev/dsp" +stream using blocking I/O calls.</li> +</ul> +When you write a new implementation, you will be using some code that is +in common with all implementations. This code is in the folder "pa_common". +It provides various functions such as parameter checking, error code to +text conversion, sample format conversion, clipping and dithering, etc. +<p>The code that you write will go into a separate folder called "pa_{os}_{api}". +For example, code specific to the DirectSound interface for Windows goes +in "pa_win_ds". +<h2> +Read Docs and Code</h2> +Famialiarize yourself with the system by reading the documentation provided. +here is a suggested order: +<ol> +<li> +User Programming <a href="pa_tutorial.html">Tutorial</a></li> + +<li> +Header file "pa_common/portaudio.h" which defines API.</li> + +<li> +Header file "pa_common/pa_host.h" for host dependant code. This definces +the routine you will need to provide.</li> + +<li> +Shared code in "pa_common/pa_lib.c".</li> + +<li> +Docs on Implementation of <a href="pa_impl_startstop.html">Start/Stop</a> +code.</li> +</ol> + +<h2> +Implement Output to Default Device</h2> +Now we are ready to crank some code. For instant gratification, let's try +to play a sine wave. +<ol> +<li> +Link the test program "pa_tests/patest_sine.c" with the file "pa_lib.c" +and the implementation specific file you are creating.</li> + +<li> +For now, just stub out the device query code and the audio input code.</li> + +<li> +Modify PaHost_OpenStream() to open your default target device and get everything +setup.</li> + +<li> +Modify PaHost_StartOutput() to start playing audio.</li> + +<li> +Modify PaHost_StopOutput() to stop audio.</li> + +<li> +Modify PaHost_CloseStream() to clean up. Free all memory that you allocated +in PaHost_OpenStream().</li> + +<li> +Keep cranking until you can play a sine wave using "patest_sine.c".</li> + +<li> +Once that works, try "patest_pink.c", "patest_clip.c", "patest_sine8.c".</li> + +<li> +To test your Open and Close code, try "patest_many.c".</li> + +<li> +Now test to make sure that the three modes of stopping are properly supported +by running "patest_stop.c".</li> + +<li> +Test your implementation of time stamping with "patest_sync.c".</li> +</ol> + +<h2> +Implement Device Queries</h2> +Now that output is working, lets implement the code for querying what devices +are available to the user. Run "pa_tests/pa_devs.c". It should print all +of the devices available and their characteristics. +<h2> +Implement Input</h2> +Implement audio input and test it with: +<ol> +<li> +patest_record.c - record in half duplex, play back as recorded.</li> + +<li> +patest_wire.c - full duplex, copies input to output. Note that some HW +may not support full duplex.</li> + +<li> +patest_fuzz.c - plug in your guitar and get a feel for why latency is an +important issue in computer music.</li> + +<li> +paqa_devs.c - try to open every device and use it with every possible format</li> +</ol> + +<h2> +Debugging Tools</h2> +You generally cannot use printf() calls to debug real-time processes because +they disturb the timing. Also calling printf() from your background thread +or interrupt could crash the machine. So PA includes a tool for capturing +events and storing the information while it is running. It then prints +the events when Pa_Terminate() is called. +<ol> +<li> +To enable trace mode, change TRACE_REALTIME_EVENTS in "pa_common/pa_trace.h" +from a (0) to a (1).</li> + +<li> +Link with "pa_common/pa_trace.c".</li> + +<li> +Add trace messages to your code by calling:</li> + +<br><tt> void AddTraceMessage( char *msg, int data );</tt> +<br><tt>for example</tt> +<br><tt> AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ", +past->past_NumCallbacks );</tt> +<li> +Run your program. You will get a dump of events at the end.</li> + +<li> +You can leave the trace messages in your code. They will turn to NOOPs +when you change TRACE_REALTIME_EVENTS back to (0).</li> +</ol> + +<h2> +Delivery</h2> +Please send your new code along with notes on the implementation back to +us at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>". +We will review the implementation and post it with your name. If you had +to make any modifications to the code in "pa_common" or "pa_tests" <b>please</b> +send us those modifications and your notes. We will try to merge your changes +so that the "pa_common" code works with <b>all</b> implementations. +<p>If you have suggestions for how to make future implementations easier, +please let us know. +<br>THANKS! +<br> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_impl_startstop.html b/src/audio/portaudio/docs/pa_impl_startstop.html new file mode 100644 index 0000000000..0f2d0ce516 --- /dev/null +++ b/src/audio/portaudio/docs/pa_impl_startstop.html @@ -0,0 +1,190 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Internal docs. How a stream is started or stopped."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Implementation - Start/Stop</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Implementation</h1></center> +</td> +</tr> +</table></center> + +<h2> +Starting and Stopping Streams</h2> +PortAudio is generally executed in two "threads". The foreground thread +is the application thread. The background "thread" may be implemented as +an actual thread, an interrupt handler, or a callback from a timer thread. +<p>There are three ways that PortAudio can stop a stream. In each case +we look at the sequence of events and the messages sent between the two +threads. The following variables are contained in the internalPortAudioStream. +<blockquote><tt>int past_IsActive; +/* Background is still playing. */</tt> +<br><tt>int past_StopSoon; /* Stop +when last buffer done. */</tt> +<br><tt>int past_StopNow; /* +Stop IMMEDIATELY. */</tt></blockquote> + +<h3> +Pa_AbortStream()</h3> +This function causes the background thread to terminate as soon as possible +and audio I/O to stop abruptly. +<br> +<table BORDER COLS=2 WIDTH="60%" > +<tr> +<td><b>Foreground Thread</b></td> + +<td><b>Background Thread</b></td> +</tr> + +<tr> +<td>sets <tt>StopNow</tt></td> + +<td></td> +</tr> + +<tr> +<td></td> + +<td>sees <tt>StopNow</tt>, </td> +</tr> + +<tr> +<td></td> + +<td>clears IsActive, stops thread</td> +</tr> + +<tr> +<td>waits for thread to exit</td> + +<td></td> +</tr> + +<tr> +<td>turns off audio I/O</td> + +<td></td> +</tr> +</table> + +<h3> +Pa_StopStream()</h3> +This function stops the user callback function from being called and then +waits for all audio data written to the output buffer to be played. In +a system with very low latency, you may not hear any difference between +<br> +<table BORDER COLS=2 WIDTH="60%" > +<tr> +<td><b>Foreground Thread</b></td> + +<td><b>Background Thread</b></td> +</tr> + +<tr> +<td>sets StopSoon</td> + +<td></td> +</tr> + +<tr> +<td></td> + +<td>stops calling user callback</td> +</tr> + +<tr> +<td></td> + +<td>continues until output buffer empty</td> +</tr> + +<tr> +<td></td> + +<td>clears IsActive, stops thread</td> +</tr> + +<tr> +<td>waits for thread to exit</td> + +<td></td> +</tr> + +<tr> +<td>turns off audio I/O</td> + +<td></td> +</tr> +</table> + +<h3> +User callback returns one.</h3> +If the user callback returns one then the user callback function will no +longer be called. Audio output will continue until all audio data written +to the output buffer has been played. Then the audio I/O is stopped, the +background thread terminates, and the stream becomes inactive. +<br> +<table BORDER COLS=2 WIDTH="60%" > +<tr> +<td><b>Foreground Thread</b></td> + +<td><b>Background Thread</b></td> +</tr> + +<tr> +<td></td> + +<td>callback returns 1</td> +</tr> + +<tr> +<td></td> + +<td>sets StopSoon</td> +</tr> + +<tr> +<td></td> + +<td>stops calling user callback</td> +</tr> + +<tr> +<td></td> + +<td>continues until output buffer empty</td> +</tr> + +<tr> +<td></td> + +<td>clears IsActive, stops thread</td> +</tr> + +<tr> +<td>waits for thread to exit</td> + +<td></td> +</tr> + +<tr> +<td>turns off audio I/O</td> + +<td></td> +</tr> +</table> + +<br> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_asio.html b/src/audio/portaudio/docs/pa_tut_asio.html new file mode 100644 index 0000000000..1c3e5bfa46 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_asio.html @@ -0,0 +1,55 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Compiling for ASIO (Windows or Macintosh)</h2> + +<blockquote>ASIO is a low latency audio API from Steinberg. To compile +an ASIO application, you must first <a href="http://www.steinberg.net/developers/ASIO2SDKAbout.phtml">download +the ASIO SDK</a> from Steinberg. You also need to obtain ASIO drivers for +your audio device. +<p>Note: I am using '/' as a file separator below. On Macintosh replace +'/' with ':'. On Windows, replace '/' with '\'. +<p> To use ASIO with the PortAudio library add the following source +files to your project: +<blockquote> +<pre>pa_asio/pa_asio.cpp</pre> +</blockquote> +and also these files from the ASIO SDK: +<blockquote> +<pre>common/asio.cpp +host/asiodrivers.cpp +host/asiolist.cpp</pre> +</blockquote> +and add these directories to the path for include files +<blockquote> +<pre>asiosdk2/host/pc (for Windows) +asiosdk2/common +asiosdk2/host</pre> +</blockquote> +You may try compiling the "pa_tests/patest_saw.c" file first because it +is the simplest.</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_callback.html b/src/audio/portaudio/docs/pa_tut_callback.html new file mode 100644 index 0000000000..f5ccaf0f16 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_callback.html @@ -0,0 +1,91 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Writing a Callback Function</h2> + +<blockquote>To write a program using PortAudio, you must include the "portaudio.h" +include file. You may wish to read "<a href="portaudio_h.txt">portaudio.h</a>" +because it contains a complete description of the PortAudio functions and +constants. +<blockquote> +<pre>#include "portaudio.h"</pre> +</blockquote> +The next task is to write your custom callback function. It is a function +that is called by the PortAudio engine whenever it has captured audio data, +or when it needs more audio data for output. +<p>Your callback function is often called by an interrupt, or low level +process so you should not do any complex system activities like allocating +memory, or reading or writing files, or printf(). Just crunch numbers and +generate audio signals. What is safe or not safe will vary from platform +to platform. On the Macintosh, for example, you can only call "interrupt +safe" routines. Also do not call any PortAudio functions in the callback +except for Pa_StreamTime() and Pa_GetCPULoad(). +<p>Your callback function must return an int and accept the exact parameters +specified in this typedef: +<blockquote> +<pre>typedef int (PortAudioCallback)( + void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData );</pre> +</blockquote> +Here is an example callback function from the test file "patests/patest_saw.c". +It calculates a simple left and right sawtooth signal and writes it to +the output buffer. Notice that in this example, the signals are of <tt>float</tt> +data type. The signals must be between -1.0 and +1.0. You can also use +16 bit integers or other formats which are specified during setup. You +can pass a pointer to your data structure through PortAudio which will +appear as <tt>userData</tt>. +<blockquote> +<pre>int patestCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + unsigned int i; +/* Cast data passed through stream to our structure type. */ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + + for( i=0; i<framesPerBuffer; i++ ) + { + /* Stereo channels are interleaved. */ + *out++ = data->left_phase; /* left */ + *out++ = data->right_phase; /* right */ + + /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */ + data->left_phase += 0.01f; + /* When signal reaches top, drop back down. */ + if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f; + + /* higher pitch so we can distinguish left and right. */ + data->right_phase += 0.03f; + if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f; + } + return 0; +}</pre> +</blockquote> +</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_init.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_devs.html b/src/audio/portaudio/docs/pa_tut_devs.html new file mode 100644 index 0000000000..1756992cb5 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_devs.html @@ -0,0 +1,65 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Querying for Available Devices</h2> + +<blockquote>There are often several different audio devices available in +a computer with different capabilities. They can differ in the sample rates +supported, bit widths, etc. PortAudio provides a simple way to query for +the available devices, and then pass the selected device to Pa_OpenStream(). +For an example, see the file "pa_tests/pa_devs.c". +<p>To determine the number of devices: +<blockquote> +<pre>numDevices = Pa_CountDevices();</pre> +</blockquote> +You can then query each device in turn by calling Pa_GetDeviceInfo() with +an index. +<blockquote> +<pre>for( i=0; i<numDevices; i++ ) { + pdi = Pa_GetDeviceInfo( i );</pre> +</blockquote> +It will return a pointer to a <tt>PaDeviceInfo</tt> structure which is +defined as: +<blockquote> +<pre>typedef struct{ + int structVersion; + const char *name; + int maxInputChannels; + int maxOutputChannels; +/* Number of discrete rates, or -1 if range supported. */ + int numSampleRates; +/* Array of supported sample rates, or {min,max} if range supported. */ + const double *sampleRates; + PaSampleFormat nativeSampleFormat; +}PaDeviceInfo;</pre> +</blockquote> +If the device supports a continuous range of sample rates, then numSampleRates +will equal -1, and the sampleRates array will have two values, the minimum +and maximum rate. +<p>The device information is allocated by Pa_Initialize() and freed by +Pa_Terminate() so you do not have to free() the structure returned by Pa_GetDeviceInfo().</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_util.html">previous</a> | <a href="pa_tut_rw.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_explore.html b/src/audio/portaudio/docs/pa_tut_explore.html new file mode 100644 index 0000000000..91c08a5b72 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_explore.html @@ -0,0 +1,42 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Exploring PortAudio</h2> + +<blockquote>Now that you have a good idea of how PortAudio works, you can +try out the test programs. +<ul> +<li> +For an example of playing a sine wave, see "pa_tests/patest_sine.c".</li> + +<li> +For an example of recording and playing back a sound, see "pa_tests/patest_record.c".</li> +</ul> +I also encourage you to examine the source for the PortAudio libraries. +If you have suggestions on ways to improve them, please let us know. if +you want to implement PortAudio on a new platform, please let us know as +well so we can coordinate people's efforts.</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_rw.html">previous</a> | next</font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_init.html b/src/audio/portaudio/docs/pa_tut_init.html new file mode 100644 index 0000000000..91bfa8d987 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_init.html @@ -0,0 +1,43 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Initializing PortAudio</h2> + +<blockquote>Before making any other calls to PortAudio, you must call <tt>Pa_Initialize</tt>(). +This will trigger a scan of available devices which can be queried later. +Like most PA functions, it will return a result of type <tt>paError</tt>. +If the result is not <tt>paNoError</tt>, then an error has occurred. +<blockquote> +<pre>err = Pa_Initialize(); +if( err != paNoError ) goto error;</pre> +</blockquote> +You can get a text message that explains the error message by passing it +to +<blockquote> +<pre>printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );</pre> +</blockquote> +</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_callback.html">previous</a> | <a href="pa_tut_open.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_mac.html b/src/audio/portaudio/docs/pa_tut_mac.html new file mode 100644 index 0000000000..bf3dafd1ac --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_mac.html @@ -0,0 +1,41 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Compiling for Macintosh</h2> + +<blockquote>To compile a Macintosh application with the PortAudio library, +add the following source files to your project: +<blockquote> +<pre>pa_mac:pa_mac.c +pa_common:pa_lib.c +pa_common:portaudio.h +pa_common:pa_host.h</pre> +</blockquote> +Also add the Apple <b>SoundLib</b> to your project. +<p>You may try compiling the "pa_tests:patest_saw.c" file first because +it is the simplest.</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_mac_osx.html b/src/audio/portaudio/docs/pa_tut_mac_osx.html new file mode 100644 index 0000000000..3af8c140ff --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_mac_osx.html @@ -0,0 +1,46 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Compiling for Macintosh OS X</h2> + +<blockquote>To compile a Macintosh OS X CoreAudio application with the +PortAudio library: +<p>Create a new ProjectBuilder project. You can use a "Tool" project to +run the PortAudio examples. +<p>Add the following source files to your Project: +<blockquote> +<pre>pa_mac_core/pa_mac_core.c +pa_common/pa_lib.c +pa_common/portaudio.h +pa_common/pa_host.h +pa_common/pa_convert.c</pre> +</blockquote> +Add the Apple CoreAudio.framework to your project by selecting "Add FrameWorks..." +from the Project menu. +<p>Compile and run the "pa_tests:patest_saw.c" file first because it is +the simplest.</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_open.html b/src/audio/portaudio/docs/pa_tut_open.html new file mode 100644 index 0000000000..1621ef30ff --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_open.html @@ -0,0 +1,52 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Opening a Stream using Defaults</h2> + +<blockquote>The next step is to open a stream which is similar to opening +a file. You can specify whether you want audio input and/or output, how +many channels, the data format, sample rate, etc. There are two calls for +opening streams, <tt>Pa_OpenStream</tt>() and <tt>Pa_OpenDefaultStream</tt>(). +<p><tt>Pa_OpenStream()</tt> takes extra parameters which give you +more control. You can normally just use <tt>Pa_OpenDefaultStream</tt>() +which just calls <tt>Pa_OpenStream()</tt> <tt>with</tt> some reasonable +default values. Let's open a stream for stereo output, using floating +point data, at 44100 Hz. +<blockquote> +<pre>err = Pa_OpenDefaultStream( + &stream, /* passes back stream pointer */ + 0, /* no input channels */ + 2, /* stereo output */ + paFloat32, /* 32 bit floating point output */ + 44100, /* sample rate */ + 256, /* frames per buffer */ + 0, /* number of buffers, if zero then use default minimum */ + patestCallback, /* specify our custom callback */ + &data ); /* pass our data through to callback */</pre> +</blockquote> +If you want to use 16 bit integer data, pass <tt>paInt16</tt> instead of +<tt>paFloat32</tt>.</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_init.html">previous</a> | <a href="pa_tut_run.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_oss.html b/src/audio/portaudio/docs/pa_tut_oss.html new file mode 100644 index 0000000000..1bb76f2592 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_oss.html @@ -0,0 +1,46 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Compiling for Unix OSS</h2> + +<blockquote>[Skip this page if you are not using Unix and OSS] +<p>We currently support the <a href="http://www.opensound.com/">OSS</a> +audio drivers for Linux, Solaris, and FreeBSD. We hope to someday support +the newer ALSA drivers. +<ol> +<li> +cd to pa_unix_oss directory</li> + +<li> +Edit the Makefile and uncomment one of the tests. You may try compiling +the "patest_sine.c" file first because it is very simple.</li> + +<li> +gmake run</li> +</ol> +</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_pc.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_over.html b/src/audio/portaudio/docs/pa_tut_over.html new file mode 100644 index 0000000000..baa99205bf --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_over.html @@ -0,0 +1,92 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Overview of PortAudio</h2> + +<blockquote>PortAudio is a library that provides streaming audio input +and output. It is a cross-platform API (Application Programming Interface) +that works on Windows, Macintosh, Unix running OSS, SGI, BeOS, and perhaps +other platforms by the time you read this. This means that you can write +a simple 'C' program to process or generate an audio signal, and that program +can run on several different types of computer just by recompiling the +source code. +<p>Here are the steps to writing a PortAudio application: +<ol> +<li> +Write a callback function that will be called by PortAudio when audio processing +is needed.</li> + +<li> +Initialize the PA library and open a stream for audio I/O.</li> + +<li> +Start the stream. Your callback function will be now be called repeatedly +by PA in the background.</li> + +<li> +In your callback you can read audio data from the inputBuffer and/or write +data to the outputBuffer.</li> + +<li> +Stop the stream by returning 1 from your callback, or by calling a stop +function.</li> + +<li> +Close the stream and terminate the library.</li> +</ol> +</blockquote> + +<blockquote>There is also <a href="pa_tut_rw.html">another interface</a> +provided that allows you to generate audio in the foreground. You then +simply write data to the stream and the tool will not return until it is +ready to accept more data. This interface is simpler to use but is usually +not preferred for large applications because it requires that you launch +a thread to perform the synthesis. Launching a thread may be difficult +on non-multi-tasking systems such as the Macintosh prior to MacOS X. +<p>Let's continue by building a simple application that will play a sawtooth +wave. +<p>Please select the page for the specific implementation you would like +to use: +<ul> +<li> +<a href="pa_tut_pc.html">Windows (WMME or DirectSound)</a></li> + +<li> +<a href="pa_tut_mac.html">Macintosh SoundManager for OS 7,8,9</a></li> + +<li> +<a href="pa_tut_mac_osx.html">Macintosh CoreAudio for OS X</a></li> + +<li> +<a href="pa_tut_asio.html">ASIO on Windows or Macintosh</a></li> + +<li> +<a href="pa_tut_oss.html">Unix OSS</a></li> +</ul> +or continue with the <a href="pa_tut_callback.html">next page of the programming +tutorial</a>.</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> +| <a href="pa_tutorial.html">previous</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_pc.html b/src/audio/portaudio/docs/pa_tut_pc.html new file mode 100644 index 0000000000..87e5f9a020 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_pc.html @@ -0,0 +1,78 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Compiling for Windows (WMME or DirectSound)</h2> + +<blockquote>To compile PortAudio for Windows, you can choose between two +options. One implementation uses the DirectSound API. The other uses the +Windows MultiMedia Extensions API (aka WMME or WAVE). +<p>Some advantages of using DirectSound are that DirectSound may have lower +latency than WMME, and supports effects processing plugins. But one disadvantage +is that DirectSound is not installed on all PCs, and is not well supported +under Windows NT. So WMME is the best choice for most projects. +<p>For either implementation add the following source files to your project: +<blockquote> +<pre><b>pa_common\pa_lib.c +pa_common\portaudio.h +pa_common\pa_host.h</b></pre> +</blockquote> +Link with the system library "<b>winmm.lib</b>". For Visual C++: +<ol> +<li> +select "Settings..." from the "Project" menu,</li> + +<li> +select the project name in the tree on the left,</li> + +<li> +choose "All Configurations" in the popup menu above the tree,</li> + +<li> +select the "Link" tab,</li> + +<li> +enter "winmm.lib", without quotes, as the first item in the "Object/library +modules:" field.</li> +</ol> +<b>WMME</b> - To use the WMME implementation, add the following source +files to your project: +<blockquote><b><tt>pa_win_wmme/pa_win_wmme.c</tt></b></blockquote> +<b>DirectSound</b> - If you want to use the DirectSound implementation +of PortAudio then you must have a recent copy of the free +<a href="http://www.microsoft.com/directx/download.asp">DirectX</a> +SDK for Developers from Microsoft installed on your computer. To compile +an application add the following source files to your project: +<blockquote> +<pre><b>pa_win_ds\dsound_wrapper.c +pa_win_ds\pa_dsound.c</b></pre> +</blockquote> +Link with the system library "<b>dsound.lib</b>" using the procedure described +above for "winmm.lib".</blockquote> + +<blockquote>You might try compiling the "pa_tests\patest_saw.c" file first +because it is the simplest.</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_run.html b/src/audio/portaudio/docs/pa_tut_run.html new file mode 100644 index 0000000000..5c70d08955 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_run.html @@ -0,0 +1,56 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Starting and Stopping a Stream</h2> + +<blockquote>The stream will not start running until you call Pa_StartStream(). +Then it will start calling your callback function to perform the audio +processing. +<blockquote> +<pre>err = Pa_StartStream( stream ); +if( err != paNoError ) goto error;</pre> +</blockquote> +At this point, audio is being generated. You can communicate to your callback +routine through the data structure you passed in on the open call, or through +global variables, or using other interprocess communication techniques. +Please be aware that your callback function may be called at interrupt +time when your foreground process is least expecting it. So avoid sharing +complex data structures that are easily corrupted like double linked lists. +<p>In many of the tests we simply sleep for a few seconds so we can hear +the sound. This is easy to do with Pa_Sleep() which will sleep for some +number of milliseconds. Do not rely on this function for accurate scheduling. +it is mostly for writing examples. +<blockquote> +<pre>/* Sleep for several seconds. */ +Pa_Sleep(NUM_SECONDS*1000);</pre> +</blockquote> +When you are through, you can stop the stream from the foreground. +<blockquote> +<pre>err = Pa_StopStream( stream ); +if( err != paNoError ) goto error;</pre> +</blockquote> +You can also stop the stream by returning 1 from your custom callback function.</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_open.html">previous</a> | <a href="pa_tut_term.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_rw.html b/src/audio/portaudio/docs/pa_tut_rw.html new file mode 100644 index 0000000000..93c7b8bb34 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_rw.html @@ -0,0 +1,79 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Blocking Read/Write Functions</h2> + +<blockquote>[Note: These functions are not part of the official PortAudio +API. They are simply built on top of PortAudio as an extra utility. Also +note that they are under evaluation and their definition may change.] +<p>There are two fundamentally different ways to design an audio API. One +is to use callback functions the way we have already shown. The callback +function operates under an interrupt or background thread This leaves the +foreground application free to do other things while the audio just runs +in the background. But this can sometimes be awkward. +<p>So we have provided an alternative technique that lets a program generate +audio in the foreground and then just write it to the audio stream as if +it was a file. If there is not enough room in the audio buffer for more +data, then the write function will just block until more room is available. +This can make it very easy to write an audio example. To use this tool, +you must add the files "pablio/pablio.c" and "pablio/ringbuffer.c" to your +project. You must also: +<blockquote> +<pre>#include "pablio.h"</pre> +</blockquote> +Here is a short excerpt of a program that opens a stream for input and +output. It then reads a block of samples from input, and writes them to +output, in a loop. The complete example can be found in "pablio/test_rw.c". +<blockquote> +<pre> #define SAMPLES_PER_FRAME (2) + #define FRAMES_PER_BLOCK (1024) + SAMPLE samples[SAMPLES_PER_FRAME * FRAMES_PER_BLOCK]; + PaError err; + PABLIO_Stream *aStream; + +/* Open simplified blocking I/O layer on top of PortAudio. */ + err = OpenAudioStream( &rwbl, SAMPLE_RATE, paFloat32, + (PABLIO_READ_WRITE | PABLIO_STEREO) ); + if( err != paNoError ) goto error; + +/* Process samples in the foreground. */ + for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i++ ) + { + /* Read one block of data into sample array from audio input. */ + ReadAudioStream( aStream, samples, FRAMES_PER_BLOCK ); + /* + ** At this point you could process the data in samples array, + ** and write the result back to the same samples array. + */ + /* Write that same frame of data to output. */ + WriteAudioStream( aStream, samples, FRAMES_PER_BLOCK ); + } + + CloseAudioStream( aStream );</pre> +</blockquote> +</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_devs.html">previous</a> | <a href="pa_tut_explore.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_term.html b/src/audio/portaudio/docs/pa_tut_term.html new file mode 100644 index 0000000000..1c72209f1d --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_term.html @@ -0,0 +1,47 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Terminating PortAudio</h2> + +<blockquote>You can start and stop a stream as many times as you like. +But when you are done using it, you should close it by calling:</blockquote> + +<blockquote> +<blockquote> +<pre>err = Pa_CloseStream( stream ); +if( err != paNoError ) goto error;</pre> +</blockquote> +Then when you are done using PortAudio, you should terminate the whole +system by calling: +<blockquote> +<pre>Pa_Terminate();</pre> +</blockquote> +That's basically it. You can now write an audio program in 'C' that will +run on multiple platforms, for example PCs and Macintosh. +<p>In the rest of the tutorial we will look at some additional utility +functions, and a different way of using PortAudio that does not require +the use of a callback function.</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> +| <a href="pa_tut_run.html">previous</a> | <a href="pa_tut_util.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tut_util.html b/src/audio/portaudio/docs/pa_tut_util.html new file mode 100644 index 0000000000..f4b5475013 --- /dev/null +++ b/src/audio/portaudio/docs/pa_tut_util.html @@ -0,0 +1,55 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet (Win98; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<h2> +Utility Functions</h2> + +<blockquote>Here are several more functions that are not critical, but +may be handy when using PortAudio. +<p>Pa_StreamActive() returns one when the stream in playing audio, zero +when not playing, or a negative error number if the stream is invalid. +The stream is active between calls to Pa_StartStream() and Pa_StopStream(), +but may also become inactive if the callback returns a non-zero value. +In the latter case, the stream is considered inactive after the last buffer +has finished playing. +<blockquote> +<pre>PaError Pa_StreamActive( PortAudioStream *stream );</pre> +</blockquote> +Pa_StreamTime() returns the number of samples that have been generated. +PaTimeStamp is a double precision number which is a convenient way to pass +big numbers around even though we only need integers. +<blockquote> +<pre>PaTimestamp Pa_StreamTime( PortAudioStream *stream );</pre> +</blockquote> +The "CPU Load" is a fraction of total CPU time consumed by the stream's +audio processing. A value of 0.5 would imply that PortAudio and the sound +generating callback was consuming roughly 50% of the available CPU time. +This function may be called from the callback function or the application. +<blockquote> +<pre>double Pa_GetCPULoad( PortAudioStream* stream );</pre> +</blockquote> +</blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | +<a href="pa_tutorial.html">contents</a> | <a href="pa_tut_term.html">previous</a> +| <a href="pa_tut_devs.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/pa_tutorial.html b/src/audio/portaudio/docs/pa_tutorial.html new file mode 100644 index 0000000000..1371c44f0e --- /dev/null +++ b/src/audio/portaudio/docs/pa_tutorial.html @@ -0,0 +1,46 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Tutorial</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio Tutorial</h1></center> +</td> +</tr> +</table></center> + +<p>Copyright 2000 Phil Burk and Ross Bencina +<h2> +Table of Contents</h2> + +<blockquote><a href="pa_tut_over.html">Overview of PortAudio</a> +<br><a href="pa_tut_mac.html">Compiling for Macintosh OS 7,8,9</a> +<br><a href="pa_tut_mac_osx.html">Compiling for Macintosh OS X</a> +<br><a href="pa_tut_pc.html">Compiling for Windows (DirectSound and WMME)</a> +<br><a href="pa_tut_asio.html">Compiling for ASIO on Windows or Mac OS +8,9</a> +<br><a href="pa_tut_oss.html">Compiling for Unix OSS</a> +<br><a href="pa_tut_callback.html">Writing a Callback Function</a> +<br><a href="pa_tut_init.html">Initializing PortAudio</a> +<br><a href="pa_tut_open.html">Opening a Stream using Defaults</a> +<br><a href="pa_tut_run.html">Starting and Stopping a Stream</a> +<br><a href="pa_tut_term.html">Cleaning Up</a> +<br><a href="pa_tut_util.html">Utilities</a> +<br><a href="pa_tut_devs.html">Querying for Devices</a> +<br><a href="pa_tut_rw.html">Blocking Read/Write Functions</a> +<br><a href="pa_tut_explore.html">Exploring the PortAudio Package</a></blockquote> +<font size=+2><a href="http://www.portaudio.com/">home</a> | contents | +previous | <a href="pa_tut_over.html">next</a></font> +</body> +</html> diff --git a/src/audio/portaudio/docs/portaudio_h.txt b/src/audio/portaudio/docs/portaudio_h.txt new file mode 100644 index 0000000000..6d60086fca --- /dev/null +++ b/src/audio/portaudio/docs/portaudio_h.txt @@ -0,0 +1,425 @@ +#ifndef PORT_AUDIO_H +#define PORT_AUDIO_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * PortAudio Portable Real-Time Audio Library + * PortAudio API Header File + * Latest version available at: http://www.audiomulch.com/portaudio/ + * + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +typedef int PaError; +typedef enum { + paNoError = 0, + + paHostError = -10000, + paInvalidChannelCount, + paInvalidSampleRate, + paInvalidDeviceId, + paInvalidFlag, + paSampleFormatNotSupported, + paBadIODeviceCombination, + paInsufficientMemory, + paBufferTooBig, + paBufferTooSmall, + paNullCallback, + paBadStreamPtr, + paTimedOut, + paInternalError +} PaErrorNum; + +/* + Pa_Initialize() is the library initialisation function - call this before + using the library. +*/ + +PaError Pa_Initialize( void ); + +/* + Pa_Terminate() is the library termination function - call this after + using the library. +*/ + +PaError Pa_Terminate( void ); + +/* + Return host specific error. + This can be called after receiving a paHostError. +*/ +long Pa_GetHostError( void ); + +/* + Translate the error number into a human readable message. +*/ +const char *Pa_GetErrorText( PaError errnum ); + +/* + Sample formats + + These are formats used to pass sound data between the callback and the + stream. Each device has a "native" format which may be used when optimum + efficiency or control over conversion is required. + + Formats marked "always available" are supported (emulated) by all devices. + + The floating point representation uses +1.0 and -1.0 as the respective + maximum and minimum. + +*/ + +typedef unsigned long PaSampleFormat; +#define paFloat32 ((PaSampleFormat) (1<<0)) /*always available*/ +#define paInt16 ((PaSampleFormat) (1<<1)) /*always available*/ +#define paInt32 ((PaSampleFormat) (1<<2)) /*always available*/ +#define paInt24 ((PaSampleFormat) (1<<3)) +#define paPackedInt24 ((PaSampleFormat) (1<<4)) +#define paInt8 ((PaSampleFormat) (1<<5)) +#define paUInt8 ((PaSampleFormat) (1<<6)) /* unsigned 8 bit, 128 is "ground" */ +#define paCustomFormat ((PaSampleFormat) (1<<16)) + +/* + Device enumeration mechanism. + + Device ids range from 0 to Pa_CountDevices()-1. + + Devices may support input, output or both. Device 0 is always the "default" + device and should support at least stereo in and out if that is available + on the taget platform _even_ if this involves kludging an input/output + device on platforms that usually separate input from output. Other platform + specific devices are specified by positive device ids. +*/ + +typedef int PaDeviceID; +#define paNoDevice -1 + +typedef struct{ + int structVersion; + const char *name; + int maxInputChannels; + int maxOutputChannels; +/* Number of discrete rates, or -1 if range supported. */ + int numSampleRates; +/* Array of supported sample rates, or {min,max} if range supported. */ + const double *sampleRates; + PaSampleFormat nativeSampleFormats; +} PaDeviceInfo; + + +int Pa_CountDevices(); +/* + Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() + + Return the default device ID or paNoDevice if there is no devices. + The result can be passed to Pa_OpenStream(). + + On the PC, the user can specify a default device by + setting an environment variable. For example, to use device #1. + + set PA_RECOMMENDED_OUTPUT_DEVICE=1 + + The user should first determine the available device ID by using + the supplied application "pa_devs". +*/ +PaDeviceID Pa_GetDefaultInputDeviceID( void ); +PaDeviceID Pa_GetDefaultOutputDeviceID( void ); + +/* + PaTimestamp is used to represent a continuous sample clock with arbitrary + start time useful for syncronisation. The type is used in the outTime + argument to the callback function and the result of Pa_StreamTime() +*/ + +typedef double PaTimestamp; + +/* + Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure + referring to the device specified by id. + If id is out of range the function returns NULL. + + The returned structure is owned by the PortAudio implementation and must + not be manipulated or freed. The pointer is guaranteed to be valid until + between calls to Pa_Initialize() and Pa_Terminate(). +*/ + +const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID devID ); + +/* + PortAudioCallback is implemented by clients of the portable audio api. + + inputBuffer and outputBuffer are arrays of interleaved samples, + the format, packing and number of channels used by the buffers are + determined by parameters to Pa_OpenStream() (see below). + + framesPerBuffer is the number of sample frames to be processed by the callback. + + outTime is the time in samples when the buffer(s) processed by + this callback will begin being played at the audio output. + See also Pa_StreamTime() + + userData is the value of a user supplied pointer passed to Pa_OpenStream() + intended for storing synthesis data etc. + + return value: + The callback can return a nonzero value to stop the stream. This may be + useful in applications such as soundfile players where a specific duration + of output is required. However, it is not necessary to utilise this mechanism + as StopStream() will also terminate the stream. A callback returning a + nonzero value must fill the entire outputBuffer. + + NOTE: None of the other stream functions may be called from within the + callback function except for Pa_GetCPULoad(). + +*/ + +typedef int (PortAudioCallback)( + void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ); + + +/* + Stream flags + + These flags may be supplied (ored together) in the streamFlags argument to + the Pa_OpenStream() function. + + [ suggestions? ] +*/ + +#define paNoFlag (0) +#define paClipOff (1<<0) /* disable defult clipping of out of range samples */ +#define paDitherOff (1<<1) /* disable default dithering */ +#define paPlatformSpecificFlags (0x00010000) +typedef unsigned long PaStreamFlags; + +/* + A single PortAudioStream provides multiple channels of real-time + input and output audio streaming to a client application. + Pointers to PortAudioStream objects are passed between PortAudio functions. +*/ + +typedef void PortAudioStream; +#define PaStream PortAudioStream + +/* + Pa_OpenStream() opens a stream for either input, output or both. + + stream is the address of a PortAudioStream pointer which will receive + a pointer to the newly opened stream. + + inputDevice is the id of the device used for input (see PaDeviceID above.) + inputDevice may be paNoDevice to indicate that an input device is not required. + + numInputChannels is the number of channels of sound to be delivered to the + callback. It can range from 1 to the value of maxInputChannels in the + device input record for the device specified in the inputDevice parameter. + If inputDevice is paNoDevice numInputChannels is ignored. + + inputSampleFormat is the format of inputBuffer provided to the callback + function. inputSampleFormat may be any of the formats described by the + PaSampleFormat enumeration (see above). PortAudio guarantees support for + the sound devices native formats (nativeSampleFormats in the device info + record) and additionally 16 and 32 bit integer and 32 bit floating point + formats. Support for other formats is implementation defined. + + inputDriverInfo is a pointer to an optional driver specific data structure + containing additional information for device setup or stream processing. + inputDriverInfo is never required for correct operation. If not used + inputDriverInfo should be NULL. + + outputDevice is the id of the device used for output (see PaDeviceID above.) + outputDevice may be paNoDevice to indicate that an output device is not required. + + numOutputChannels is the number of channels of sound to be supplied by the + callback. See the definition of numInputChannels above for more details. + + outputSampleFormat is the sample format of the outputBuffer filled by the + callback function. See the definition of inputSampleFormat above for more + details. + + outputDriverInfo is a pointer to an optional driver specific data structure + containing additional information for device setup or stream processing. + outputDriverInfo is never required for correct operation. If not used + outputDriverInfo should be NULL. + + sampleRate is the desired sampleRate for input and output + + framesPerBuffer is the length in sample frames of all internal sample buffers + used for communication with platform specific audio routines. Wherever + possible this corresponds to the framesPerBuffer parameter passed to the + callback function. + + numberOfBuffers is the number of buffers used for multibuffered + communication with the platform specific audio routines. This parameter is + provided only as a guide - and does not imply that an implementation must + use multibuffered i/o when reliable double buffering is available (such as + SndPlayDoubleBuffer() on the Macintosh.) + + streamFlags may contain a combination of flags ORed together. + These flags modify the behavior of the + streaming process. Some flags may only be relevant to certain buffer formats. + + callback is a pointer to a client supplied function that is responsible + for processing and filling input and output buffers (see above for details.) + + userData is a client supplied pointer which is passed to the callback + function. It could for example, contain a pointer to instance data necessary + for processing the audio buffers. + + return value: + Apon success Pa_OpenStream() returns PaNoError and places a pointer to a + valid PortAudioStream in the stream argument. The stream is inactive (stopped). + If a call to Pa_OpenStream() fails a nonzero error code is returned (see + PAError above) and the value of stream is invalid. + +*/ + +PaError Pa_OpenStream( PortAudioStream** stream, + PaDeviceID inputDevice, + int numInputChannels, + PaSampleFormat inputSampleFormat, + void *inputDriverInfo, + PaDeviceID outputDevice, + int numOutputChannels, + PaSampleFormat outputSampleFormat, + void *outputDriverInfo, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PaStreamFlags streamFlags, + PortAudioCallback *callback, + void *userData ); + + +/* + Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that + opens the default input and/or ouput devices. Most parameters have + identical meaning to their Pa_OpenStream() counterparts, with the following + exceptions: + + If either numInputChannels or numOutputChannels is 0 the respective device + is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() ) + + sampleFormat applies to both the input and output buffers. +*/ + +PaError Pa_OpenDefaultStream( PortAudioStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PortAudioCallback *callback, + void *userData ); + +/* + Pa_CloseStream() closes an audio stream, flushing any pending buffers. +*/ + +PaError Pa_CloseStream( PortAudioStream* ); + +/* + Pa_StartStream() and Pa_StopStream() begin and terminate audio processing. + Pa_StopStream() waits until all pending audio buffers have been played. + Pa_AbortStream() stops playing immediately without waiting for pending + buffers to complete. +*/ + +PaError Pa_StartStream( PortAudioStream *stream ); + +PaError Pa_StopStream( PortAudioStream *stream ); + +PaError Pa_AbortStream( PortAudioStream *stream ); + +/* + Pa_StreamActive() returns one when the stream is playing audio, + zero when not playing, or a negative error number if the + stream is invalid. + The stream is active between calls to Pa_StartStream() and Pa_StopStream(), + but may also become inactive if the callback returns a non-zero value. + In the latter case, the stream is considered inactive after the last + buffer has finished playing. +*/ + +PaError Pa_StreamActive( PortAudioStream *stream ); + +/* + Pa_StreamTime() returns the current output time for the stream in samples. + This time may be used as a time reference (for example syncronising audio to + MIDI). +*/ + +PaTimestamp Pa_StreamTime( PortAudioStream *stream ); + +/* + The "CPU Load" is a fraction of total CPU time consumed by the + stream's audio processing. + A value of 0.5 would imply that PortAudio and the sound generating + callback was consuming roughly 50% of the available CPU time. + This function may be called from the callback function or the application. +*/ +double Pa_GetCPULoad( PortAudioStream* stream ); + +/* + Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for + the current host based on minimum latency. + On the PC, for the DirectSound implementation, latency can be optionally set + by user by setting an environment variable. + For example, to set latency to 200 msec, put: + + set PA_MIN_LATENCY_MSEC=200 + + in the AUTOEXEC.BAT file and reboot. + If the environment variable is not set, then the latency will be determined + based on the OS. Windows NT has higher latency than Win95. +*/ + +int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate ); + +/* + Sleep for at least 'msec' milliseconds. + You may sleep longer than the requested time so don't rely + on this for accurate musical timing. +*/ +void Pa_Sleep( long msec ); + +/* + Return size in bytes of a single sample in a given PaSampleFormat + or paSampleFormatNotSupported. +*/ +PaError Pa_GetSampleSize( PaSampleFormat format ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PORT_AUDIO_H */ diff --git a/src/audio/portaudio/docs/portaudio_icmc2001.pdf b/src/audio/portaudio/docs/portaudio_icmc2001.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dd074b7d334d9b0d4415330c2a123131aa130115 GIT binary patch literal 50968 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 AA^-pY literal 0 HcmV?d00001 diff --git a/src/audio/portaudio/docs/proposals.html b/src/audio/portaudio/docs/proposals.html new file mode 100644 index 0000000000..0f9b8cb641 --- /dev/null +++ b/src/audio/portaudio/docs/proposals.html @@ -0,0 +1,36 @@ +<HTML> +<HEAD> +<TITLE>Proposed Changes to PortAudio API</TITLE> +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252"> +<META content="Phil Burk, Ross Bencina" name=Author> +<META content="Changes being discussed by the community of PortAudio deveopers." +name=Description> +<META +content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis," +name=KeyWords> +</HEAD> +<BODY LINK="#0000ff" VLINK="#800080"> +<CENTER> +<TABLE bgColor=#fada7a cols=1 width="100%"> + <TBODY> + <TR> + <TD> + <CENTER> + <H1>Proposed Changes to PortAudio API</H1> + </CENTER> +</TD></TR></TBODY></TABLE></CENTER> +<P><A href="http://www.portaudio.com/">PortAudio Home Page</A></P> + +<P>Updated: July 27, 2002 </P> +<H2>The Proposals Have Moved</H2> + +<p> +All PortAudio Enhancement Proposal documentation has moved. On the web site, it is now located at: +<A HREF="http://www.portaudio.com/docs/proposals">http://www.portaudio.com/docs/proposals</A> + +On the CVS server it is now located in a module named "pa_proposals". +</p> + + +</BODY> +</HTML> diff --git a/src/audio/portaudio/docs/releases.html b/src/audio/portaudio/docs/releases.html new file mode 100644 index 0000000000..aec80a1cb9 --- /dev/null +++ b/src/audio/portaudio/docs/releases.html @@ -0,0 +1,339 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> + <meta name="Author" content="Phil Burk"> + <meta name="Description" content="PortAudio is a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> + <meta name="KeyWords" content="audio, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> + <title>PortAudio Release Notes</title> +</head> +<body> + +<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > +<tr> +<td> +<center> +<h1> +PortAudio - Release Notes</h1></center> +</td> +</tr> +</table></center> + +<p>Link to <a href="http://www.portaudio.com">PortAudio Home Page</a> +<h2> +<b>V18 - 5/6/02</b></h2> + +<blockquote>All source code and documentation now under <a href="http://www.portaudio.com/usingcvs.html">CVS</a>. +<p>Ran most of the code through <a href="http://astyle.sourceforge.net/">AStyle</a> +to cleanup ragged indentation caused by using different editors. Used this +command: +<br><tt> astyle --style=ansi -c -o --convert-tabs --indent-preprocessor +*.c</tt></blockquote> + +<blockquote>Added "pa_common/pa_convert.c" for Mac OS X. Start of new conversion +utilities. +<p><b>ASIO</b> +<ul> +<li> +New Pa_ASIO_Adaptor_Init function to init Callback adpatation variables,</li> + +<li> +Cleanup of Pa_ASIO_Callback_Input</li> + +<li> +Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo</li> + +<li> +Deallocate all resources in PaHost_Term for cases where Pa_CloseStream +is not called properly</li> + +<li> +New Pa_ASIO_loadDriver that calls CoInitialize on each thread on Windows. +Allows use by multiple threads.</li> + +<li> +Correct error code management in PaHost_Term, removed various compiler +warning</li> + +<li> +Add Mac includes for <Devices.h> and <Timer.h></li> + +<li> +Pa_ASIO_QueryDeviceInfo bug correction, memory allocation checking, better +error handling</li> +</ul> +<b>Mac OS X</b> +<ul> +<li> +Major cleanup and improvements.</li> + +<li> +Fixed device queries for numChannels and sampleRates,</li> + +<li> +Audio input works if using same CoreAudio device (some HW devices make +separate CoreAudio devices).</li> + +<li> +Added paInt16, paInt8, format using new "pa_common/pa_convert.c" file.</li> + +<li> +Return error if opened in mono mode cuz not supported.</li> + +<li> +Check for getenv("PA_MIN_LATEWNCY_MSEC") to set latency externally.</li> + +<li> +Use getrusage() instead of gettimeofday() for CPU Load calculation.</li> +</ul> +<b>Windows MME</b> +<ul> +<li> +Fixed bug that caused TIMEOUT in Pa_StopStream(). Added check for past_StopSoon() +in Pa_TimeSlice(). Thanks Julien Maillard.</li> + +<li> +Detect Win XP versus NT, use lower latency.</li> + +<li> +Fix DBUG typo;</li> + +<li> +removed init of CurrentCount which was not compiling on Borland</li> + +<li> +general cleanup, factored streamData alloc and cpu usage initialization</li> + +<li> +stopped counting WAVE_MAPPER when there were no audio cards plugged in</li> +</ul> +<b>Windows DirectSound</b> +<ul> +<li> +Detect Win XP and Win 2K properly when determining latency.</li> +</ul> +<b>Unix OSS</b> +<ul> +<li> +Use high real-time priority if app is running with root priveledges. Lowers +latency.</li> + +<li> +Added watch dog thread that prevents real-time thread from hogging CPU +and hanging the computer.</li> + +<li> +Check error return from read() and write().</li> + +<li> +Check CPU endianness instead of assuming Little Endian.</li> +</ul> +</blockquote> + +<h2> +<b>V17 - 10/15/01</b></h2> + +<blockquote><b>Unix OSS</b> +<ul> +<li> +Set num channels back to two after device query for ALSA. This fixed a +bug in V16 that sometimes caused a failure when querying for the sample +rates. Thanks Stweart Greenhill.</li> +</ul> +</blockquote> + +<blockquote> +<h4> +<b>Macintosh Sound Manager</b></h4> + +<ul> +<li> +Use NewSndCallBackUPP() for CARBON compatibility.</li> +</ul> +</blockquote> + +<h2> +<b>V16 - 9/27/01</b></h2> + +<blockquote><b>Added Alpha implementations for ASIO, SGI, and BeOS!</b> +<br> +<li> +CPULoad is now calculated based on the time spent to generate a known number +of frames. This is more accurate than a simple percentage of real-time. +Implemented in pa_unix_oss, pa_win_wmme and pa_win_ds.</li> + +<li> +Fix dither and shift for recording PaUInt8 format data.</li> + +<li> +Added "patest_maxsines.c" which tests <tt>Pa_GetCPULoad().</tt></li> +</blockquote> + +<blockquote> +<h4> +Windows WMME</h4> + +<ul> +<li> +sDevicePtrs now allocated using <tt>GlobalAlloc()</tt>. This prevents a +crash in Pa_Terminate() on Win2000. Thanks Mike Berry for finding this. +Thanks Mike Berry.</li> + +<li> +Pass process instead of thread to <tt>SetPriorityClass</tt>(). This fixes +a bug that caused the priority to not be increased. Thanks to Alberto di +Bene for spotting this.</li> +</ul> + +<h4> +Windows DirectSound</h4> + +<ul> +<li> +Casts for compiling with __MWERKS__ CodeWarrior.</li> +</ul> + +<h4> +UNIX OSS</h4> + +<ul> +<li> +Derived from Linux OSS implementation.</li> + +<li> +Numerous patches from Heiko Purnhagen, Stephen Brandon, etc.</li> + +<li> +Improved query mechanism which often bailed out unnecessarily.</li> + +<li> +Removed sNumDevices and potential related bugs,</li> + +<li> +Use <tt>getenv("PA_MIN_LATENCY_MSEC")</tt> in code to set desired latency. +User can set by entering:</li> + +<br> <tt>export PA_MIN_LATENCY_MSEC=40</tt></ul> + +<h4> +Macintosh Sound Manager</h4> + +<ul> +<li> +Pass unused event to WaitNextEvent instead of NULL to prevent Mac OSX crash. +Thanks Dominic Mazzoni.</li> + +<li> +Use requested number of input channels.</li> + +<br> </ul> +</blockquote> + +<h2> +<b>V15 - 5/29/01</b></h2> + +<blockquote> +<ul> +<li> +<b>New Linux OSS Beta</b></li> +</ul> + +<h4> +Windows WMME</h4> + +<ul> +<li> + sDevicePtrs now allocated based on sizeof(pointer). Was allocating +too much space.</li> + +<li> + Check for excessive numbers of channels. Some drivers reported bogus +numbers.</li> + +<li> +Apply Mike Berry's changes for CodeWarrior on PC including condition including +of memory.h, and explicit typecasting on memory allocation.</li> +</ul> + +<h4> +Macintosh Sound Manager</h4> + +<ul> +<li> +ScanInputDevices was setting sDefaultOutputDeviceID instead of sDefaultInputDeviceID.</li> + +<li> +Device Scan was crashing for anything other than siBadSoundInDevice, but +some Macs may return other errors! Caused failure to init on some G4s under +OS9.</li> + +<li> +Fix TIMEOUT in record mode.</li> + +<li> +Change CARBON_COMPATIBLE to TARGET_API_MAC_CARBON</li> +</ul> +</blockquote> + +<h2> +<b>V14 - 2/6/01</b></h2> + +<blockquote> +<ul> +<li> +Added implementation for Windows MultiMedia Extensions (WMME) by Ross and +Phil</li> + +<li> +Changed Pa_StopStream() so that it waits for the buffers to drain.</li> + +<li> +Added Pa_AbortStream() that stops immediately without waiting.</li> + +<li> +Added new test: patest_stop.c to test above two mods.</li> + +<li> +Fixed Pa_StreamTime() so that it returns current play position instead +of the write position. Added "patest_sync.c" to demo audio/video sync.</li> + +<li> +Improved stability of Macintosh implementation. Added timeouts to prevent +hangs.</li> + +<li> +Added Pa_GetSampleSize( PaSampleFormat format );</li> + +<li> +Changes some "int"s to "long"s so that PA works properly on Macintosh which +often compiles using 16 bit ints.</li> + +<li> +Added Implementation Guide</li> +</ul> +</blockquote> + +<h2> +<b>V12 - 1/9/01</b></h2> + +<blockquote> +<ul> +<li> +Mac now scans for and queries all devices. But it does not yet support +selecting any other than the default device.</li> + +<li> +Blocking I/O calls renamed to separate them from the PortAudio API.</li> + +<li> +Cleaned up indentation problems with tabs versus spaces.</li> + +<li> +Now attempts to correct bogus sample rate info returned from DirectSound +device queries.</li> +</ul> +</blockquote> + +</body> +</html> diff --git a/src/audio/tonegenerator.cpp b/src/audio/tonegenerator.cpp index 367e02d46c..a3985c07a2 100644 --- a/src/audio/tonegenerator.cpp +++ b/src/audio/tonegenerator.cpp @@ -41,19 +41,28 @@ ToneThread::ToneThread (Manager *mngr, float32 *buf, int size) { this->mngr = mngr; this->buffer = buf; this->size = size; + this->buf_ctrl_vol = new float32[size]; } ToneThread::~ToneThread (void) { + delete[] buf_ctrl_vol; this->terminate(); } void ToneThread::run (void) { while (mngr->getTonezone()) { - if (mngr->getAudioDriver()->mydata.dataFilled >= - mngr->getAudioDriver()->mydata.dataToAddRem) { - mngr->getAudioDriver()->mydata.dataFilled = 0; + // Control volume + for (int j = 0; j < size; j++) { + this->buf_ctrl_vol[j] = buffer[j] * mngr->getSpkrVolume()/100; } + + if (mngr->getAudioDriver()->mydata.urg_remain <= 160) { + mngr->getAudioDriver()->mydata.urg_ptr = this->buf_ctrl_vol; + mngr->getAudioDriver()->mydata.urg_remain = size; + } + + mngr->getAudioDriver()->startStream(); } } @@ -128,18 +137,16 @@ ToneGenerator::initTone (void) { * * @param lower frequency * @param higher frequency - * @param samplingRate * @param ptr for result buffer */ void -ToneGenerator::generateSin (int lowerfreq, int higherfreq, - int samplingRate, float32*ptr) { +ToneGenerator::generateSin (int lowerfreq, int higherfreq, float32*ptr) { double var1, var2; - var1 = (double)2 * (double)M_PI * (double)higherfreq / (double)samplingRate; - var2 = (double)2 * (double)M_PI * (double)lowerfreq / (double)samplingRate; + var1 = (double)2 * (double)M_PI * (double)higherfreq / (double)SAMPLING_RATE; + var2 = (double)2 * (double)M_PI * (double)lowerfreq / (double)SAMPLING_RATE; - for(int t = 0; t < samplingRate; t++) { + for(int t = 0; t < SAMPLING_RATE; t++) { ptr[t] = DTMF_FREQ_MIX_RATE * (float32)(sin(var1 * t) + sin(var2 * t)); } } @@ -150,12 +157,10 @@ ToneGenerator::generateSin (int lowerfreq, int higherfreq, * * @param idCountry * @param idTones - * @param samplingRate * @param ns section number of format tone */ void -ToneGenerator::buildTone (int idCountry, int idTones, int samplingRate, - float32* temp) { +ToneGenerator::buildTone (int idCountry, int idTones, float32* temp) { string s; int count = 0; int byte = 0, @@ -178,13 +183,13 @@ ToneGenerator::buildTone (int idCountry, int idTones, int samplingRate, time = atoi((s.substr(pos + 1, s.length())).data()); // Generate sinus, buffer is the result - generateSin(freq1, freq2, samplingRate, buffer); + generateSin(freq1, freq2, buffer); // If there is time or if it's unlimited if (time) { - byte = (samplingRate*2*time)/1000; + byte = (SAMPLING_RATE*2*time)/1000; } else { - byte = samplingRate; + byte = SAMPLING_RATE; } // To concatenate the different buffers for each section. @@ -237,25 +242,34 @@ ToneGenerator::idZoneName (const string& name) { */ void ToneGenerator::toneHandle (int idr) { + manager->getAudioDriver()->mydata.urg_remain = 0; + int idz = idZoneName(get_config_fields_str(PREFERENCES, ZONE_TONE)); if (idz != -1) { - buildTone (idz, idr, SAMPLING_RATE, buf); + buildTone (idz, idr, buf); - manager->getAudioDriver()->mydata.dataToAdd = buf; - manager->getAudioDriver()->mydata.dataToAddRem = totalbytes; + float32* tmp_urg_data; + // Free urg_data pointer + tmp_urg_data = manager->getAudioDriver()->mydata.urg_data; + if (tmp_urg_data != NULL) { + free (tmp_urg_data); + } + + // Init struct mydata + tmp_urg_data = buf; + manager->getAudioDriver()->mydata.urg_ptr = tmp_urg_data; + manager->getAudioDriver()->mydata.urg_remain = totalbytes; // New thread for the tone if (tonethread == NULL) { - tonethread = new ToneThread (manager, buf, totalbytes); - if (!manager->getAudioDriver()->isStreamActive()) { - manager->getAudioDriver()->startStream(); - } + tonethread = new ToneThread (manager, tmp_urg_data, totalbytes); tonethread->start(); } if (!manager->getTonezone()) { manager->getAudioDriver()->stopStream(); + manager->getAudioDriver()->mydata.urg_remain = 0; if (tonethread != NULL) { delete tonethread; tonethread = NULL; @@ -297,23 +311,29 @@ ToneGenerator::playRingtone (const char *fileName) { // Decode file.ul expandedsize = ulaw->codecDecode (dst, (unsigned char *)src, length); - + floatdst = new float32[expandedsize]; ulaw->int16ToFloat32 (dst, floatdst, expandedsize); - - manager->getAudioDriver()->mydata.dataToAdd = floatdst; - manager->getAudioDriver()->mydata.dataToAddRem = expandedsize; - + + float32* tmp_urg_data; + // Free urg_data pointer + tmp_urg_data = manager->getAudioDriver()->mydata.urg_data; + if (tmp_urg_data != NULL) { + free (tmp_urg_data); + } + + // Init struct mydata + tmp_urg_data = floatdst; + manager->getAudioDriver()->mydata.urg_ptr = tmp_urg_data; + manager->getAudioDriver()->mydata.urg_remain = expandedsize; // Start tone thread if (tonethread == NULL) { - tonethread = new ToneThread (manager, floatdst, expandedsize); - if (!manager->getAudioDriver()->isStreamActive()) { - manager->getAudioDriver()->startStream(); - } + tonethread = new ToneThread (manager, tmp_urg_data, expandedsize); tonethread->start(); } if (!manager->getTonezone()) { manager->getAudioDriver()->stopStream(); + manager->getAudioDriver()->mydata.urg_remain = 0; if (tonethread != NULL) { delete tonethread; tonethread = NULL; diff --git a/src/audio/tonegenerator.h b/src/audio/tonegenerator.h index 9dae275525..7243514cf0 100644 --- a/src/audio/tonegenerator.h +++ b/src/audio/tonegenerator.h @@ -56,7 +56,8 @@ public: virtual void run (); private: Manager* mngr; - float32* buffer; + float32* buffer; + float32* buf_ctrl_vol; int size; }; @@ -73,8 +74,8 @@ public: int idZoneName (const string &); - void generateSin (int, int, int, float32 *); - void buildTone (int, int, int, float32*); + void generateSin (int, int, float32 *); + void buildTone (int, int, float32*); void toneHandle (int); int playRingtone (const char*); diff --git a/src/global.h b/src/global.h index 03eff32dac..6f420daccf 100644 --- a/src/global.h +++ b/src/global.h @@ -57,7 +57,7 @@ typedef short int16; #define MONO 1 #define SAMPLING_RATE 8000 #define SIZEBUF 1024*1024 -#define FORMAT 2 // for 16 bits format +#define FORMAT 4 // for 16 bits format #define OCTETS SAMPLING_RATE * FORMAT // Number of writen // bytes in buffer #define OSS_DRIVER 0 diff --git a/src/gui/qt/configurationpanel.ui b/src/gui/qt/configurationpanel.ui index c02d0e9d4c..9b402883c7 100644 --- a/src/gui/qt/configurationpanel.ui +++ b/src/gui/qt/configurationpanel.ui @@ -156,7 +156,7 @@ </widget> <widget class="QLayoutWidget" row="0" column="1"> <property name="name"> - <cstring>layout17</cstring> + <cstring>layout19</cstring> </property> <vbox> <property name="name"> @@ -730,188 +730,135 @@ <rect> <x>20</x> <y>10</y> - <width>126</width> - <height>196</height> + <width>133</width> + <height>157</height> </rect> </property> <property name="title"> <string>Supported codecs</string> </property> - <grid> + <widget class="QLayoutWidget"> <property name="name"> - <cstring>unnamed</cstring> + <cstring>layout18</cstring> </property> - <widget class="QLayoutWidget" row="0" column="0"> + <property name="geometry"> + <rect> + <x>10</x> + <y>20</y> + <width>110</width> + <height>120</height> + </rect> + </property> + <grid> <property name="name"> - <cstring>layout11</cstring> + <cstring>unnamed</cstring> </property> - <hbox> + <widget class="QLayoutWidget" row="0" column="0"> <property name="name"> - <cstring>unnamed</cstring> + <cstring>layout17</cstring> </property> - <widget class="QLayoutWidget"> + <vbox> <property name="name"> - <cstring>layout9</cstring> + <cstring>unnamed</cstring> </property> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="QComboBox"> - <item> - <property name="text"> - <string>G711u</string> - </property> - </item> - <item> - <property name="text"> - <string>G711a</string> - </property> - </item> - <item> - <property name="text"> - <string>GSM</string> - </property> - </item> - <property name="name"> - <cstring>codec1</cstring> - </property> - </widget> - <widget class="QComboBox"> - <item> - <property name="text"> - <string>G711a</string> - </property> - </item> - <item> - <property name="text"> - <string>G711u</string> - </property> - </item> - <item> - <property name="text"> - <string>GSM</string> - </property> - </item> - <property name="name"> - <cstring>codec2</cstring> - </property> - </widget> - <widget class="QComboBox"> - <item> - <property name="text"> - <string>G711u</string> - </property> - </item> - <item> - <property name="text"> - <string>G711a</string> - </property> - </item> - <item> - <property name="text"> - <string>GSM</string> - </property> - </item> - <property name="name"> - <cstring>codec3</cstring> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>G711u</string> </property> - </widget> - <widget class="QComboBox"> - <item> - <property name="text"> - <string>G711u</string> - </property> - </item> - <item> - <property name="text"> - <string>G711a</string> - </property> - </item> - <item> - <property name="text"> - <string>GSM</string> - </property> - </item> - <property name="name"> - <cstring>codec4</cstring> + </item> + <item> + <property name="text"> + <string>G711a</string> </property> - </widget> - <widget class="QComboBox"> - <item> - <property name="text"> - <string>G711u</string> - </property> - </item> - <item> - <property name="text"> - <string>G711a</string> - </property> - </item> - <item> - <property name="text"> - <string>GSM</string> - </property> - </item> - <property name="name"> - <cstring>codec5</cstring> + </item> + <item> + <property name="text"> + <string>GSM</string> </property> - </widget> - </vbox> - </widget> - <widget class="QLayoutWidget"> - <property name="name"> - <cstring>layout10</cstring> - </property> - <vbox> + </item> <property name="name"> - <cstring>unnamed</cstring> + <cstring>codec1</cstring> </property> - <widget class="QLabel"> - <property name="name"> - <cstring>textLabel1_4</cstring> - </property> + </widget> + <widget class="QComboBox"> + <item> <property name="text"> - <string>1</string> - </property> - </widget> - <widget class="QLabel"> - <property name="name"> - <cstring>textLabel1_4_2</cstring> + <string>G711a</string> </property> + </item> + <item> <property name="text"> - <string>2</string> - </property> - </widget> - <widget class="QLabel"> - <property name="name"> - <cstring>textLabel1_4_3</cstring> + <string>G711u</string> </property> + </item> + <item> <property name="text"> - <string>3</string> - </property> - </widget> - <widget class="QLabel"> - <property name="name"> - <cstring>textLabel1_4_4</cstring> + <string>GSM</string> </property> + </item> + <property name="name"> + <cstring>codec2</cstring> + </property> + </widget> + <widget class="QComboBox"> + <item> <property name="text"> - <string>4</string> + <string>G711u</string> </property> - </widget> - <widget class="QLabel"> - <property name="name"> - <cstring>textLabel1_4_5</cstring> + </item> + <item> + <property name="text"> + <string>G711a</string> </property> + </item> + <item> <property name="text"> - <string>5</string> + <string>GSM</string> </property> - </widget> - </vbox> - </widget> - </hbox> - </widget> - </grid> + </item> + <property name="name"> + <cstring>codec3</cstring> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>layout18</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="text"> + <string>1</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4_2</cstring> + </property> + <property name="text"> + <string>2</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4_3</cstring> + </property> + <property name="text"> + <string>3</string> + </property> + </widget> + </vbox> + </widget> + </grid> + </widget> </widget> </widget> <widget class="QWidget"> @@ -1248,7 +1195,7 @@ Montreal, Quebec H2T 1S6</p></string> <data format="XPM.GZ" length="58862">789ced5d596fe3b8b27e9f5f114cbd0d0eea6475625cdc878eb3b4b34ca72799e9745f9c07c74b76c776363b07e7bfdf629194488ad49249e4f40151109292488a923e7dac85a2fff9dbc2e9d1e1c26ffffce5fea1f370d95de85e74260bbff51e6f6f67fff7affffdf72fbfae2c2d2f34971696165717967ffdc72fbfe21f0bdd05682c37d61a52ffcc7a87f40eebbb4a6f2a7d47e93da57f17fafa4aa3b7be2274e8487d7d49eab8a4f43575fc96f533d2cf58df547a53e953a5f794fe22f48d95f5de866caf2df58d25a9c34ce96beaf8b9d4cf96cf56f9f890f5333a2edb1b2bbd29757c547a4f1d1f495dd7c78b44efb13e507a43e9db426fae6ef49af27c7da93797943e50fa9ad4f145ea49fd65a577947ea8f5ee1ad7df557a5f1e872dadcbe3f8c47a97daefb2fea0f4a6d2ef95de53faa5d4757de849bdbbacf496d03babcd5e47f6ff52ea9d25a583d2d7a48e7da927f59f125d5ecf27a537947ec47a97eacbfe4c94de51fab1d2fb528767a927f5af94de913a74b5de93e7df577a5f955f14fad96aa7af9ee758eac9f36d28bda1f0b22775dd1e9e28bdaff403a9f79695bece7a2f799e23a5ebe7f9ac74f5fc7045eaba3e7c4af43e1f5f557a43eac0f8eaae25cffb4eeafa7ee354e90da5f7a4aeebe3b5d23baa3d7e3fba3d7d3fe14ee9ea7ee250e9eafec195d4757dfc5debfd06eb6b4aefabf62fb42e8fc367a9f79795ceef5b6f2db99f33a927f7734fe90da57f937a52ff20d1657fba4a6fa8fefc99e8f238bf2fd43b7d3f51e9fa7a6e95aefa8f9b52d7f5e14ce91dd5de86d0fb0d7d7df855eaba7fd854baea0fec285dd587b6d607f2f8b5d2fbaafd2f5a57c7f97dee27fdc153a5ebf6264ad7f5ffd2baac8f37521f2c2bfd4ce90da5ff10fa20391fee4b3d29df52ba2edf49f4019fff46e91da533df0c06fa3882d2d5f1af0f4a1f683d4a94fa24622e4add123117a56e89988b52b744cc45a95b22e6a2d42d117351ea9688b928754bc45c94ba25622e4add123117a56e89988b52b744cc45a95b22e6a2d42d7f177308d821399bf77544f979e4b598c32ef6b08f033cc70bb55de2155ee3cdbcafe8e30bdee210ef7084639ce03d3ee0233ed1df09e9cf38c519decebb87ef2bd53147ac768d2f8cb601612dfbf7136ecefbaa3ea2600bb70855dbb883bbf8b960dbc5366171847bb83fef7ebfbd54c51c1e58dc16da0e3f0eeef81df91dbfbc4bdbfb848b23622d282cf99570f4c7abb6e379dfc1b7962a98c31b1a3ffddce6fb7b52aac53f091107344a5ff2d87c42e8f8eb2daf0fbf25fd7973d4e1293392e0a5eff8a3a0ec6221b785b6a5b7eef7bca53ce6e8e915f39bbd2de7f916c43f57c17a2b7ebb903c966f6447ae166c6b29be08cdbaddde5bdf3b6c187c342a28bbe4e1b0255c278edcc0267e05c42d00e8f8b80ef0ad7b3e5f298b39465c96cb06849b2b42c8359ce1267433c797b1e36d0d88db2e0ab8f2c41db108a56539f602bfa9f324fbe1cd31077d838f724740ea4786bf60e02b07e7597b0fcedfbae7f3957298f372dc00d7ac327f911597e5ac818fb108a7699915dc14c8c40e9cc105f48cba874ead9ea7fdd0c67da3676df8d56f7defc8df4cb928b7751a855deeea602b507694e1bac5b7eef97ca50ce6f08b974baecd32c47321cec93c0db2e0521f37c38364e3ad32838ae3dfac73749df69709bb3d204e931bc915fd774dffabbec14d5e3ffeae900f9a72513ee6006e1d9edb0a9786a1c373776fddf3f94a29cc2dfbb8c4ba4b6730cae19c15abb52fc9fee073a267744163ab331a1242cd7657a13016581fcf6151d99151760727b9656fd9fa53e561f8d6fd9eb714638ec63eafdd649559ceb7afe0dadb5ec5f8b1652f96b2ce98e7743fde97e7c685a587e42734b3f13698900771ef29dfa211f9166790d766618c46956bc2234ee9fca76f7d0f5e234598a3912ec45f3725caa80d9e8c7bfca4f62f57ed2b3c57e5ac6a3c87fb70477e64533c49dcc7198ef101a6f81d66788477d9676ff1dc1fd2d2a7e7fa0c973084195c12b70523bad4b3676a7da6f90c3a30a61acd40e91f7847e567844260940e71421ecc928e1e877009f7e40bbfa49c293816c80dae7ae7df568a30079fcac4df380b96ef4b265137b6d5c4fe4f55fb6ad87307256b54b0e70861a94fd9f1c6ca1c5bdee439e6ba4e12af4bda8147efb9a6b0e9cf3f402bcb4584c5cf057ddbf58dd6701eb80eb204ca32e47b4821cf0d82fc3548fb4dcfd66bf319db956a2fe144c8b1a2037d49ec39b82859a302cf116b14e604888b8c676bf35cb0ceb6739e0d62a6dc3a84310311706ff154f83cb6853d8171ee39a64551ecf7937ccc4149eee2d859418e425bfc894ffa37ecb9b29833edb97c8cc343b9bc00f99f498cc3e539ff465c6322085d2ef46e064e7156a65fcca98955483ed8b0b04e7b5e5c5780b96e0e772dbb1126f20ef2b84e656089add27c43a5ab4eed3928392e97e7395f3e1436c9f619e13d8f50e9fe84e9caf11c6d897f41c8dec91cff4ee36cb64edab359e9dc6ce2e11253da1cb8497bc66401dad7f72131c7fe68c817ddf194ff421e4288eb5655995563ff7295b900863d57d287b0ecb9c3dc92599e3347d16d63ffae1e95b23c0703c2e83159edf6fe84b518a5d639a4f5c6734edaceb199aa93e1397811ef029dcbe52e957f33f2c09f79144d7c06f2904d3bf27b282efdbe92873908fba397e18c395c046cc0849bac5cc33969d7e5f2ef567ceeba548dd7f39ce32fc038cb412ecfe9d82db6c0e226d00c3fb4b8a7a351a5fbca2832b849ed77788ed84af11379d98e1da86a3c18fb3fdb769b7d9daead598fe4610ebf0438ab2036a66c3bb75e12d123241c7a8ef7b1879b79715e279fbb92df0bae61c6e772633336cfd93618f779cb3caef6d93c67645c9969b2e56d2ef5cc0ae051362dc3fce4f09cc54d60e571a1aff6764c4ecc9c636a5c67e6681d928bb96e96af60b7242765e78c185164c2c20a86e6e1898cd6375f9b467c4ee57269cf09b1a42d9be96c1693e7f27d0887e71a9eb34f8de3724434796ed78ec5391cc8c74c5b0ebc36059c5b9cc628b679ce9e1940bd36cb735c86fc629b17ad5929ecc398c7e71025ce1d5bcf325c5421a606570e9739f32838bf15f6750fb3a36726df1afeab50f76a7bce1335b5388547c5bc3c04581c28222c840593af02790b93a3a41de8f09c937b25de73cb8f1c3b8fd80cef69ef049f4c8e53dbccdf8ff7945c9edb7478a56214173edbf5bde7001ac1d788ad2e3dbce7ccb374f2ad79db4dd27aba2f17738e9de3cb45ad1bfcf0cc7bcc7925ce1be5d85a6453c1a3c55781f94966ec0ea6bcc7b6e79cecabe5f34a9e9b94f673c5f6fc1628aa26b93cd7b6b8a354ae8afcd6d574ae0878edb990e00d95bfb238cb9a7f97999f774863ab98a3796d6e84f4c4267c9d3d07de397f8c22cd5b6ced59f69c930720567379cea8af6d35cf3dc8f4c3e1b90da757e30ccfdd67b82c67f3e749de577279cef65bd3b9b7c44df464fd3697f4493fe9a33c37d3f15bf385ce7a62d88f8615e6d873d725be427815cff96d2df23a537e38e23da6cde662ceb60f7f64e6c505ec28b8346d446ec9e63907ab561f183fe4d796e5b85d7a6be610a32b88cfa5398313b56713b59de68d3d305e64fcaec7333121c9af96f0339356560dae4bfc34d39e2b9789b0ecb9f27eab27f2e8f014fb9c16cfb9b195877c9e0bcd37b7da6cf31e8be7dc6cbe555ef2dc83cd6564cd1d1147cf5c216fe263c68493f9bc623612f9142f066f9c786b98b9089e73492894ba971773ceece42fac7c6bc95cadc573b963bbc34b9ef920786c1c67abaa22cfd97c159887697d3721f754e4393cb2ec46af9d305f29c0dcb5b68792586f9abff4320d5c383ee441e29b56fad69ff854b7b39ab49dda732539d3b2e7cef3de6b87973c2c0426dfb0556571cc716e7b82e79a165f79470998581cb5ce67a9ca730dab8dc2797df54b01e63a094f64e36dde6f02c907f5fb92157d5e6c2575137e34f2adaf9957720139b90bc76fcde484a83fd9785b259e7338cc6bd1d9795299d7a8cc73b7561b7e0b08e6397bb370fedc5e300ee6650d62466f79a8b8a289f18d57ea8526f65cd9d62c7bee22ef8b5b273eb7eb8eae3831b84667a52ad9733cea99e7c85eb39527d57da8ca734e1ee2366b27e0a2884e136fcf213627a4107367c118981f7327deb2b93ea3b79d6b6d131afbd2f85cc9595036cfe5f1a39b6fd579247517d0e21a9d4bafca734de71c1607e186fd0dace6daaa3ca7a2d7693b632b5b36219426b6dec7cbf1ababfa1488f5fba3584f5e4eec5a2d7e29c20c8d6487b23e18350d7baee437f98e3d27da7bc26bfe4aec0c76f026b5313df34a1e93f9235bc416296725b9d86af61cd77062678487a9980bcf2b99d8f3eabeeb79ead5790ef7ed6f64a9f777c4a12d7a73d6ad3cc72eeebd359eca4809cc75d03f4fe44f4fd91b1f278215eb861ecab973413f965a39d4fc68bda3697cae24e65c9ef36df024d8cfbf9e08bc40dfcab38a2dc9c556e539f12e79e7cae5e607aaf31cc7654a9c43e639ea9752df1afee9e52e8f756ac5d5923cab3d57c498537268e62cd4d18ecafecbfa16b68cf85ce9b547f025688f5a9c5d7a9ef0d8988d6bd671fc43e215b3debeb17fa9c479ccb97b95798ef717ae8f42e89fd3ecf492dff11f7839c2f10369b4cae44c61e4ceedc41bd8b2ca5c72066b8dc6bc7dec9bf1347b44b66276a5a39999b928be6d10e2b90cefb5cc33e3c4389659338e9ea93e66dd01f12d56ee7976ecd89df33d843b37fbd8386665897196c7a9e4417cd0ef218c2b58f172841127232bed30cb21bed9c41cc53bcce59e174260c6e6c3dfd5f10a1e49609d15fbef75a9ef2176325fd3fc20ab4b1e6b7bce7cac8e7dcfe6f3f1ab9527357dd5a32c16f029e1a6ec9a08a9afbbebe662bf8a6fd9be67cf43e79e8b1da7a5c2ba4c2b7e8e202611ab21f9befbbac89b794e185dc1cb6c7be4b3acf96b243c7a55e50af10b5c65e6d8a5f24d62db89cf6d8ad506f116ce0939c46770e7fff29438eb0e4710f2e167b01d5ef781fcd4291e93bdb8091db21bc70070e79bcfc2e74142cfc8df07f2b7ee704cfdf0f7615f7c718b47d4fe0c0506a7f3febab5e2fa73df8cfc6be15ff2154a45d1e89e7dc12e1c10a20af334342e1f54cba1951587e7d6dfe31c51a4545b67932cfcb273d856e77d65d5c4b1e7fecb57f49daf545f4f18ce3cebcc59f3e4b057cc581f4d2c9efb3ecfafdcfffbe575eba613dfadaa58b1c96dcb7812b2c53eba58f3e7e6f265cacf254994fb156b6cffbddf87c01659619bbcc666096bec230b790c29cfcdbd37957b7f1b9a1bf54ee79b605bcc3026ff7b884fc15253ff4c82f83b385ae025b1e77e8a95cac9537dd4cf148f0803019ff75dcedda7bbb52efa407f3d7122eed30f98fa675245cc6949e69ded64e35c1f51a08f6d9d8703a0ff6bf47b08ed7c6e62b2761073b774ccfbf646cca5c22b03ce7e8e5f01c12631db4b92d53f224ea9317b8adb74be06af36360dadb543e3ee4be4b9aa8220a2baf82c249d394c96df3eaf8ad8247c9a6b81006ee008c5bccb75f5053e582b324d6cfe34d6779af1d7a723dc4a66ac00b5b108e7380cc589517c952884bf06123c074311b9a636c4b70fd64a50740d47b84eef53c1db04f738c6276a690cad74bd46c2ce3936685ba7f6f5fcaa323c774ac7bcbf60103117161abd8e047a080153fdcee20f7a26e24edf132a1e04d7c84c83989706537af6e2c91fd3336b094b3bcd55c13d3dc9699a3d23dc3e0a1c93d5d3a2273862643cc240cdeedc127692380fb5ef99274f3d7a54fd78e49537c56a9a6dfebda60798d179fa12a9544eac43774c489ca2f82e312707c1f938d9c63db5a1381487b84d75c53b764af7635baf6020ed39be2f219e8310f746cc85c5e405badb6da103f38bcea0121bb465665d7872aebf4b8c933c0f40ae97cc04854769f513e2da3ac34a3ca34ac09d6431f20a037379457d3ece7599e7668a5d9b023bb28764a3b6d3160889399683b8428d4a14efceb6ea53bab2a5e895fc46a304cf718b5e8c47cc95131ecbf6388ed74e5732a7777906721d89470fe6c8e6d2775da09339418f4e13815562b7a9594bd86522064123aae0b87e78ee07f1a4e04048eb19ebe22d4aeb9d38746622826c84b66f25163ec69c9a9ffbc73d7d8d65ec3931c3c0bf3f62ae8c306371448a79cef8f681ac37f915ea3a3353c35979eb51e7f84539168dc16dc144b2969e1387fb0223e249499ecbff5d0818a4f612fbad49691a0fd9cee335eddae96a13c2560bc51e39da92fb8d188fad8a87cbf15c287a1331972fbc7afabde4288101c173e69a21642bb5d53aeb6c0d11f7b4d2df39c4b1b4e8041f12beee68ec92df729dca919af889ed3042e494acf47b14489ae9b857becd0f2de2448d6830ed3ee6e24bf9a6703bf41fa1f888da7e0afd2e19db0ea17b704a0c3911f6a8b01f794f097b2e2c117321c1167b09fcf536bde3438939e639e38b6ec154fa7fb27deea43f49a5e52a3a5bd25aa367ced8a3b148f2c4a2fcc2465873f42cd14597e4b982fedda74cc83c675a9fcc73b0adbcd912d11fb6e63c5fe4d01508bbe007db78e2ad929e45299e0b49c45c48c4334d474acef69c2b9e33ec7ab6d2adf71c26621c250e427e4ec2b34cd0c156d8808f4b5d708767652469cf15f58fb84dfb32c29e4b7a21ceca3c37947fcb5e6d766c657b33b100c5fb26cb94b3e7421231e717810ecbba9f04786e94c58688a7249ee391b2e3b46fda521ea9f47685e5e5fb6587923c67d973e6ac7969cf9d9a9e72416b23ee97b326077be3497e83af3df2dcbb094cf819682ff394b5a987e746ca9e33c625b6a75ea4b720d0435c90c6e59e9903d3b89df00492f9bf34864ba40ec379cca4ec84da51dfae727c2ec3733c86bfa4ab7d91b5300dfa98fb6caf6d2719dc0deaa988eebda416204764c6b2d7ca9e1be6d97310f855b388b990f00828be09ddc031fb93722685e00e234a4b969a8c9534e8dd5f17bf8e04d2a6532312790f633342c1f113834f84374825d6a9ddafb00d331561c6222f52fbd26a55b2a30ccfc9d8728bfde545dc00b16eec76deec059cb1cd3aa41a138ef08937e996e37e77e25de0b743c70f5b9263a5671c686f3fe621aa0bee894c02bdef7b34aaece9cc8fbd8616dd5995d1a2e313fe052f61bf19712ef1bcac1a5fed118cd8846a127300e156b10c79230d7745cdac48bb51b02e21d62a0d8f464e6e28fa457d1a17fdde35e1f252bc5d847cd01904eafdb6f88e82aeee2b217028475a7a0ff95706443fc3bf688c81bc47c4dccf2c345abef91783ef3fc721622e4add123117a56e89988b52b744cc45a95b22e6a2d42d117351ea9688b928754bc45c94ba25622e4add123117a56e89988b52b744cc45a95b22e6a2d42d117351ea9688b928754bc45c94ba25622e4add123117a56e89988b52b744cc45a95b7efdcffffcf2ff6d14cd7e</data> </image> <image name="image1"> - <data format="PNG" length="5550">89504e470d0a1a0a0000000d49484452000000ad0000003008060000006357fade0000157549444154789ced5d7f6c53d7bdff1cd42107a5d57545a7eb48ab6c34d09cae6836655a9cb5aa6fd56a38a41a71fb24926c15b940d525ddb497b0e975091525ddf40a2e6a9bac1ae020ba38480f0c4f908427aa5e57f4c5792a2ff64437bb2a15b660c21645b14523624593beef8f1b5ffbdad73fae03234fcdf9e743b8e77ccff79cfb3d9ff33ddf73ee31ae02380ae06e2111115d2322229a5a445a20badbf5ace03717d951000200a906148968e24a028009030109e1a4ad6c09a7d90dbb2984fd4fdb31b69ab15aeb5dc16f36b2ab35149cbf49144e023de7fd48f302109700b33ee4ac02da0c46785b012f5b31e015ac1e7531ad4844c2071202f1f28caa179d66377cdbe69179680dbbdf1db282cb1f575593d1b240c47f41c4def023804583350b770d03713f1ace64e0bbf837badf1db282cb1f2b32edfccd59ea3c634438e9ffa7a864e3c308ed16565c86152c896599d67293a8f963c8066b5e7c728f316cb0c1f8961f22112d870e5ac1e587259976fee62c351f03d2199d22d70681075a94bf5d8f8430fa133ba478020683095bff5c1d63730609a9dfb897c4b822110d1ff622f4bf411426ebf7ace87eb61be9b569641a1afe5ff8d222114d9c9b40cb8f5be07df8eecc44fced3b347c6418d1cfa3885e89c1bade82a1578730b6718d6ef9f7423f2dd48c1e586e12193f4e211d95aa8b062425ccfccc0d7b3d80078bec4349c118d0fc49aaea280397accd702db789a43341f4bcd70327040420293a68fd6d6ce530b8b77fd9bb24de7dfb29752e8d0024442e84ee8a6118de1ca537cf7854fd0127d077c0a37b20df0bfdb4b08869f905a28643295d0c3bbbc70d631dca26f17c0823972cba55ac857183bbba683a1c56eae67913dcad6de8de22c2f7890fd6a4157d810124930925cfe8e1a330da372d6bc61589c837e643c7931df03eba748310af1135b6d955efa9c96683f7b0b7a6017cb7f5ab9a697d178902017ff571d7cd2ed096f2166b1f0b22fc0f6b4df15c9805381186f7a567aa32287181a8d161571875ff8efd48776fd5ec40cb1744895b09846e85d0f8fcd692f22d5f1061fdd2e2c92211952b2fce12d5ca4c961b44304017b3890b448ee704a4e7d2007233d0e86b47116edb54b2bf621b98ee81ad573fcb0d22984af7b78a699b6e123df6bebe2841d7e618bc5bd4a3353fd5cab08538ba2d0dc7c675153b2c159aa1cedd3b95fa9d4e41f754275e2372ffb603d12b51cd36399d02fa7675031bd6b18ea79d949e4b83abe710fc402a6298d8c529eadfdb8ff45c1ad6f556b84e8cb1ac9ede1309842f7914c3c926eb7a2b9a9eb0a1ef5ffb542fcee699a1ce1372db86de1e82e5a96636f9a7a3347c645829cbf3266506f9e8d71398ec68d07cf159bdb5d2ccc814c636ae61ed97ef50cb6b2fa866a46ce2ea390c3a0761dd6551d604d5e8c7d5734a7bb3fa65d71efe73a78beae27913865a8760d9ce23b918c757a2072211351fd31f2510cca50d36180346beb2e892570a7b3ee76059a08a715cbbad409f00206e7591edf40cc52e4e91385b392ad1d86647f44a145c3d8799912944c642885c08c1e91464460a48e8d82dc2729b4880000048cfa521fca2a5485ef0ada0f292525fa72100f07b0e50e7ee9d080406609bb383e74df8ddb65e34d96c68ab6f43f44a142327c6d0b8d98ef6cb77147d3b4fec947d4e007cc604090077cba06aae356955fe3dfca5b7643bfdbff70180222f9bf6efd88f3a731d04009bba9a614d5ac1f326cc8c4c61f4f051a51fd27369f49ceb8177b70f7af4b3cde5decff0975e99f19d02868f0c23994ca09d6f475b6b1b465f3b0aeb7a2bac492b5e38e2c633cfb7c0f285fcfe15a61d3c3b4323e11a18910f8376ab1b9e4d6214183979f7e2bbfb77b861aac2576abf7c873675356bea944d5c3d07eb7a0b84a70574b477a8184d5c200afd35a4e9e3b63c61a3ac8cc88510864f7a91cf241f9d9d509827ebaa64d3ccc814a4b8843d6f0c283a74ef12e1e8e854d5e3f2dda0670eb528e522a743f03eca9827afeeee5ddd70bdbc930d16f8ef80ccd45ddbdbd1f8fc5616f48d52f02f1c32e9d30000fb130e74ef16e1658c15d6d3d6da06cbeb0315fb4124a2c6cdb97665175d7af56b696d81b85b44f6b9d329c07ec0a37abfde7dfbe9f43959f7269b0d8e23236c950079c7eb74a6464634d810f9aac8260000deb5b8ab715ccf89eae2b7631bd7b0c8a510bab6b7a3fbd96eb9430a18c53667c774388c370f79d0b8d98ea60b5715b9ded58ce5bfa85468865cc11b246e75292fc509018803ddbb4570f59c223ff5d78ca247ff1f0695fadaf9768c6d5cc33c87a34a792d8315004c7634b0a1578794b2ddeff515680f382d829cdf2ca8da77eaf77eb84e8cb1ac8ffee6210f02810118c2464c87c3183e320cdf980f020093d59493070183adfd2a3d0afbc1122272056f90d0daa2eacf503c54937eb8829cc14240f2ef0988d78852a1191267892c17894c1993f27c3a1c8648440f48009ad290c35b10e4c58f4eecfcd08d503b8ad323c081f569ec89d726b710d310e0fb2c56152f7b1963eec5bf2700186e4cd0b0e120a4bf06c1474d18f8b81fb89253f585d7dc882c10795733d67ef90ef5fd7900e14b2178e6d2409e8f9c4d01488059aea7cd7380464e8c010076fe5e44908862576290768b4a7edb6e2b1ac7014f724c293fdc7e10de8e4e4dfd63965c5de14b214885f5c724b8000cc6a59c3e00a69f5ba7f6a95bdb90f87b0c19a4d0041b0c9c519e593a3a219a8bdb533863a9fb21c7ae49e47c4fbbd90e6f0dfa896b0beabf22bb665a2900095c3d87f9afe7f18000c07d0635adeab318fed20fc0ad59595f93dcfb7baed42e3f1fc3493732286fb09ad8d0c0bc797f1f0410393b4e936f04940e1d3ee685f5f894e25a70f51c3e7a770226b3093001be311f8287c24afe2cc358b6f7216bb4b6393bf2a74e270444f9a8129dc88f1387c2a1d22e0e67cb95af8f4200e0c92b9fcf64f9d36fa11cf1f5812226f71ef04058d45fa54f3ca78fe1cd51dad4d50c270418f83accbc3b81bab5754a3fbc79c8a3e887386ad2afb0feb6d6360cbeda5f36ca907c680d56196edfa17032b56426f4478b5798d9d4d7049cda9c010c4b675ccf746517415c589c622ae46bf9718b6aa3617e2e859ef77a00c8061b0c48987434b05803635ec698a3a39345f95c44c16eb64302106b60acadb50d0054f2b27f0fb50e29f5666c29e599f7c458c981d6f9879d4af9fecdbf53a466e50762929c3faeae4fcf40b69bed2a7db3ed11af91b2e110ae0f413a3781b18d6b947ee868ef50b52fcbd07af5b3dbd4f50fee286db0861b379445f8aa54a60e4bf639d706e1cef38fb492db6a02bd62c4e88bee25d7e7fbacbcc1363aecf0ee9657dfdcf038057da3b28f749b485c208a5d9c22cbf1296a7c2ec788ed7c3bfa36f7297fdbe6ec4058bdf838b8a797b221997c8691000ceeed57b537ebc371f51c1ab75b947cde7ff72acf030109dcf0386557c55983e9dbde4efc1593525ed8e558949627bf84cfa8670642bc40dfc5f64cfc6542edb3e6cd082211b9db3b6af669558ccf181b7deda8f2dcf17341152db1dc266aba70953a9e76d2e0f39e5cf4a0abd6a84116d70641bfc8ad40ab4decb00454f8d2a114f66e77c3ba417b44f2b7ef50e7cb3b4bc658b59275bd1507f70dc2b2de0277bb3a3ecbf32664e6e68b62a9008ab62a2dfba6a8e75c8f2a4f7615ad1a58d788845fb468c63ff313cf9be07d7b08d820c7a7bd79b155add539cf9bd0313e59fd0643611420188277356322c961a8fc3657d30fbead2e65506be9c7d573103f0e14e997ca5b13944ad6f556f8c77cf032c6d8fe8b44037a76c0f2d0f5600c13db4ac7692ba5be40049eeba61a76c88cf0be547e6746bc4674f0e44198322614eead0720a1fbd96e240c09fc6e5bafea7048762b1271796a13cc0282e930fab7f5226148c070cb88404c42dbe32e98be6f42eca19c1ed9330fbefff642300b48181270f7ee29a967e4ec38d5a58c4afe6c7d0943027d2ff6156d5444ce8e53fab33482e93086df3a082f634c5c2012bb45086601a6272db03cd5ac7b2365f8bc176d8fbb30e96850f5c3f0612fb85b0645afe83f62e87e5684c96042e4564ce9876cb94afa718f7325771eb5ea93e2123a7e2c42b038107b2ad7cf0cfb4e916e86ad77e1d496744597a09a148ca5d07cde00dc9aacba7ece20e0e06f1f5ed6875b56f0dee12abd3ee58156376857dd5d31580070588ca09fd5a1f7d9ea7ddd74462adb30cb0251d34da2e10b44be8b44c31766a8e92651353b6a2bb8fcb17aa63548987db5f269aea5a48918aa3e6f7bf4f5d24c3bf8ce1d8aa78b99dbc6bbd1fdf2d24e1ff10b4475df0282d753707cc7a879a84324a2ecf3e0f5144c8f3e7cd74e8ff10b44c9d5c5ae51e2da2c014648f108606e842d9340e386a59f139efcf42a850c16c4c212069d0238430a75dfceb527f2c50df24c9b542505a70091abed9bbff99bb3743a638414c83d315a050c7d2f278fe1f82c55f425e76a5b6cd592420960d391ca3ef6d5d75f28d921ebf69da25aca5583d10b449ee99c7eb4577d6cb27d8168cd1f8af51fdfee46b2c4e2b11a1489c8f896fcf5b32d6384ff65b52fcdce149f539e721a617a54ffa9ac9cc112f544d57239ab8083ff92238ccca7443de7b5df57af2986eee7aa3bee291291fb6410a7e7b54f03e6f7f3aa8af1d1a4f44f335800b09b80995dee8af1da721d506bb96ad033ed57c91bfc24a27adef99f41cd7ab79ef0c3779c88afd14519be14433a232c6eb0a4d4ed7d109aed9596d04e09408a2f969b8e4aaa3879d70f00a759fb7d79a62d70ffe9a38af17291882cef4ee074d4aa29677cbb9a182afab4b3af6aef742d2545be02faa6017f89a89462b865f42ad7e1b596ab068be4991b0b5eb4a364fd81b81fcd1fcbf746e8add7c6abcf86e43f0f5e2fd64b66a8a50d50c4b5e506afe7f2255733d6f112637f7bc50dce50dceeec377faedbda86db74539e41e25c71bf99b920686ff10cb5ca9cd66606c425d8be7b6f7cd8c64700cf877ebc703205f6c7091c4c0089afe75579ec26c0d5aa3d826dbcfbbe316d91bcb89a6911d3ae378be1693f9a8fa590b836abcf70e39192ed707ca7582fc42508e6a50d50c1ac2dd7f19de2fcd3df662cf51b376c997051fe744640c3213f06dfb943be8b7fa3c43579713cf8ce1d7aec7dbf3283e497eb35c510fb658be69a6195685bfc08b170445905845a8b0d2e96025ace00ec4380bde507fb2005f64171be8a69b34baea7de813d47e47b0fd807ea0f1027be0be07157917e166305c3ba8f4c2b58b4eb2d8c7e340780e0651d8c6b6e2cd90e9460dac201a51be311ed765cd7ceef658cf95f7e86ed771a35cbc5d3931888993070cc0f4fc282787ab2281f6715403b8ce87e6e132bf5e5c22a403d82b3e87a20a6fa48b12f10017b7b1eebdef363f2b31430ed071647c8f89385165945ba3e5d5c6fdc0af6961fa92ce93e08b8102dcad7fba30a86751f9956aac0b4f9d8792685c1b333d5196e19a64509a645e180d28930376acbd560da7cec788ab12927c0e93c6b62e3ddb8f153236215168fab7a7fa41ec159ccdfe9627f9c9077aee68a4706cc023219e84fa5188917f0f0013f428b3b9c434fdb35f22d5fa62d6c97adc98df1ed46d05e378ebefe30a3bd6eec7726c059e5e723290bfafe63aae262a51cd3de4f9fb6149a1e7d98a576189576565a3b996d2e8476c83e7225bd568dad664cd3f21713fbe30470cb517684b8735f78549f2a30d2a6237ed8c7807527d5ffcf25a58a619cfbc9b485ed9a7a1a68dcc094a9cecb18eb78ea3176e3a746b46d917df6d3512bec87a5b2a7d74e7f1e2ad98ee5e0d36abe8747749cd38e49c0b7aa93bb4a00d0662df6417c5180bd3d01d4975e0d03d2a26f5a43aac2f70b7fe9070ceabbc386b6945f84dd6fa6cdf7699de67049e648ae66ccf543c6c6b7cb5192b0c106f6861ffc17f269b46c3e9188263f25f2244a470f968b4f9b8fd9b872353b9c808438e7a8387015a69500f85f4491e5779ef40373e519161080afd4dfff549d74f87ef968e152950dab4c79c3ed3b4bdacad5ebd3569297dcc0d88d5fbbc125e5ffd97ac20f76288575fb4ed1ce7db3c4def0a3e77cf17967557bef914f9be6f5fbb47cde65855a518172184ecae1b1a69be50d77950079ca32db8a57e9d5e0e8664769c32c97aa60da42749a8d556d89969393cad4dd53a655b7ab3ab9930fc9e122ad3867353346e4ab62bd601620056a6fa700c07f7e42536ea955bde51a51e37fcd63eb096d86b5f1464ced907dfaf1ed6e98b96051be342fe0b1f7fd485c54cf38454c2b00183427510bf38d7d1e2a69976553c1ce523528fdbc4ac32a23e7b1f7fd085e264a5c9badbcf8d1407d3e6df572bdac749c530bf3cbd77d9b31ad787b209eaaf9fad4c1b333144f17cfb45dc6e26ff44492e3aeec580af1f064911e36de8d2927e07f99b1e8a3b24f9fdcc098f4abad6cc89ad68c320c04fc30be9fc2e4a7578bf457ee3d706c5cc79ce6b06ea69dacafe13c6d0cbaeb713aabbf1aa992bc91337e340700f6861f3b8fcfd2ba7da7a814262e1245f2be2cd01ba7d56328d93867974d3bce594e6eec972d9a4c3d1033413c4ee4ba5df9949b6541ce27bc334e23a9e2afb36d7c18de567b91c15ade9d40a1cf9dc5f1edf221a55233a4eb87eb58ea15236c4dc53ba0e98c849e2807f138a9084675c38c48b22fa27732a1bdfab67af5de87c01904445e31547d6a68e7be59aa7d52d4c6eca9b27505a7e2f63b13e878ea3145affcfb239c66373a5eaaed904cf0f255ea3cc355d447cb80e26947c9724e731846ab005b26b218878d408a35229d29ff9b194e7318d2cf73ae01bf403410073c27b4df2367901079c58dc98774dcc1769968e44c6579aafb69bd4cde43d6c380300be80b44b46cb3641a29e12b95c2a12d465dc7dc7a9b62ba99bc1cee772614f94ea7ba7ffa9f5433edd04f727165bba9f661e2d8b88ed10e6d06b2f1e1924c2dfd6a2b1bdd6644af4639404200369c3eef5776a606622604e27e840dda37bc0f6d71636a8711de979e51ed508dfc65d16035facb690e23f51b7d062b00706c64eccebf69fbf6695ede0a76dd26d2bc9fb69cc56ba241c0d48bf281ee4a49efdd5e5db618fa9fd77f9b61e1b9d75ab1d279d952cf135fdfbddf90a8f57cae4844becf62887116e57c6a2cadcdc4363e0cce20c0581784ed470ed83209b4ac379574c98297af92376c4138294709b20cdec52dfd1caf4844c39762f047653b09c46d30734158b816f8b6cd97b89f7681c8fe31109ed6f1edd86617a6be570747de251385e9e034b0e74af5f7d3eab92d7105bf3958f226707e81a8f91874ffd682eb71ed8f1ded634184bfb4562da7cd1a85ff45c7b2bfe87805fff958f177c40c97893acfd4f6b56eadd865accd2558c16f0656f53b624d37e56b40d3997bab12671030b4a5ba7b6857f09b8b55fd8e58f6806f2d715c3d71d8d42bc615835dc18aa8fbb77113d766a93f6044207e77ee9d2d8cffddef0e59c1e58f35fd36ae04392cd1f721e0cfcccb5b7766a16a9fd59c0e62684b0b5a78a86e6859c115ac0697f42be4f906ecfb2c060b6781e77f8248cdabe380d91d18f1078d00567e0377059786ff07eb0134671ac4ce230000000049454e44ae426082</data> + <data format="PNG" length="4951">89504e470d0a1a0a0000000d49484452000000ad0000003008060000006357fade0000131e49444154789ced5d7f681b579eff3c735be4e02d52d91629d062972658de6341da181a850d917a85ad1c173aba5d88eddd522949c93a774b6ba770e44771ec72248e127267efe2247230b565c8462a38b67364b1547cc85e925a2a592c19a7d8c1596ce32eb6d01ad79883effd31d64823cd483392b34db77a603e4de7bdeffb7edf7cdfe77ddf77de8cb00ae006809d4222225a2022220a6d236d11ed743f25fcfe62d10e3a3cbb48a1052253cf18a18d086db765d1da47d4726f8a8888be6dc34bf8ddc5821a4eaf100dcf12692fdc26dcda764c95a81d22720e51c9814ba81a55352022b2f6e56754b568ed235a4c6c944288122a424515698b8f4f0b615435d83e3e5d72dc12e6c5bc15a65756c9d4b3b3cc9a0b4d3d63a590a184393167055a21d20e3d7d86cd44ed85db25c72da12cca5e985e5925ed850218b37b98d043849e31420f91ddcf670b6e471729b4a85cce4e382e115157cf0d721e7366fd75ba3b896689161717bf33210911d1f0d030d1c6ce4de88dc40675ba3bc979cc49fb0f59c979cc49345b98fca7a19f14ee0cc35eb84d73ab4494a09c2534477f17c6a504d1d4ad6932ee33d1e97ded64dc6712fea4fe7dbaadfd3bc1eca7dbda05fd77ca3186ddc359e3f19b532d054de4a7a19f22a6ddd822d50caba43847a70a8a710b715ce731a7e846580fdba9abe706d10a51ff403fcdb9e7c87ad82eaa33159e7ae6199788d79f5676c6216885446360dc67e299b6c009bcd3fa29665aeb7d95316820bfc39a064245c5b8d6be31c50e454422461df384640790668936c21b343c349c533ecdd28e842a39af17c14cb448aa998d8868ff216bd60a34373a9773bcfe1efad162eef16637007000fc00ec09a2dd577c001c0094a1b3360ccf5b66c815d7dd307a1f9815cb93c3fe77e661ffc9abcc9fa6af14ce87a7a8e9f851a17fabd5868e4e77de76e9e85a2172fcb611b14731499bac561b5a8f3543bbf7555677c84af1f538b4155a4cdc0ac0f31263e9f222e3213a73ee0ce2eb7118f718611ff4b2a49e9ec14d441ef0d7d28b718f11fbf799d0fa612b3c2c25cfe69ea3ba410700a0eb72174c070f306fcf0deabede2db4d5eb0d585e5e02004c7d1082b7711793b233a9b754897ac3f0ec65cc354b64fbb04e90975eb4155a7459bb6038a68366f76ea6543f6d8556b037a99f8b88baaf79e0bbe3cfea4baf3760a0be1fda231a6c3ebf8bf9019409378a886a7eef038cdb8ea210b96a79879d98077ad7cdaae4c9e1c9c755d06d11e57338b349ac8f2ea885e3b09d6ca37314190f916b83289fe3d6d8cd883d8a415ba145d41be6ffc6c3b05a6de0c021180ca0f1b80bba041107fe26c5d7e3b039ebb2e4c52ec6849bb4f6b73838001e7727351d3f8a60f0246ceb36e8f506741e69c77e9309ce0a17628f62e81df4a2a6d60cd76c4adfba410738700000238cf003a85cd78becb52cef17fefb93afdcb2768e5d1e0100415eb2749de802f4dbe3d0608665793ff47a03a2de30faafdd10c621be1e47d39d26f88f8f428d7eb6759b483f171159ac36745fefc6f2f2129af5cde0ea398c9cf7c1b8c708cbf27ebc71fd0dbcf1761d74b3fcfd1798b675688a7a230530a23e003a6e835471cd03bd9f16c7b0e9d87ec2014306934932e52c514d83fc6402f8196fdc5305db211b1a1b1a458ce622a270248c2af34fb318fac03e13256544c7c3e8fed4837426191b1a1198c7454435b5293da2de3046664670eafc594187e6632ed81b9b44fd340c6cd04faf1c48b51b0dc3f31263eeb4be9b8f35a3e1fda3acf59893262311916dc63d46388f34c0f2f661363ad04f135f566133ee010098f759d07cdc050f632cb31fae9e43d5c767f38e43965de3617876a9d7afaebe0eaee32e24af5bad36983bdda2fbeb6e6b27ff1d3f0060bfc904cbf55e56c601d06d11f9512023ea6c887e9de51300004f058a66d87474dff4c145f999d2b397b1e883309c471a70bafe347f433218c5b66ec36424824faeb851536b867d7c5590eb618ca5dfa8f9f014358437c871d82edc140e1c3003341f77415ba14dc9ff4a23e871e67c87d05fb3be199ebd8cb9af2d0beda51c9603e06ddcc5fa3fea4fb5ed6ccdd01ee08c1c5fbf9a13d93776790cf6412fb3bc7d98f9017c72c58d60f0240c912a4c4622e8bede8d01ef003800e5c6f2943c70e8a83f231ec78c71d085891ac21b64abaf138d6778265c907e7804c161397058fecb125c2b44f3e129726d10e9c6898c300ad7272311b88888dd4061b16c3a9a5e7320dc00c97269721ea7fe585590dc6262db4cdc5c5c2483d680c0171330c68c38f9f9c9ac9835fa200c0fe363b9e6ebad883c0867c59ba2fadb0cb3e6eea4de412f009e3d278201cc3f9a47e37197d0bef35c3b2c6f1f6622a6deee4f4adfc878884e7e785290e9fa3ca888c95abe886431d5d25fe685eb1aad0edd172ff1766e10d51ccc66ccf4154bcd38a8d52fb3ff7c455ba1c5d8d0081fd3d60da228068c7ce593eda8757f153adf2c4e7e3acec7ab143b6a3a6a76ef669e5d8c990e1e60a3efbfc06e0c7a59e7b9761163745ff3c0746b9a6a1acc0806030080a96b214487c2883e08e3f4072d920cd37aa455f87fb6751b6a6acda86b7020be1e07070e7abd0149e613b58f8465f5b5e92dc0767d4d45b9d02ad93e93c9205c17cb69f9f82cb35cef6597aef732cbf55ed6d1e966c989c2eb9f6d8f1f80de3d4c350d66e8825a682acaf9b83e6d1c52fdf12b4e21fa65f6cfd573888e87d1f2458485be88b04c747d1e649bcfef62659b890d8a2c03886d335a81e88b65ef3093a5753f70fb9f97004de1f2937836983f4470d1f61293a75eddbfd4c10fbfa0e737eb6b68bad80420c5985ef32eb6b69b310f63ccded8c426f493427d73b5197e006bbb19e3eaf9c14f9797fcf7407dbfd0ef9229c57a9e41afec44737cdc28b4bf54db29484dcaf7c7fc7cfd99ccfe944f645eff54fba43dae15a253837cdc1da808207067049ebd4c1887c68646917da84641fa994de2fe3b4e9c11317de64a99fc7719508ea219f0472370180dc8551c4603e80430fcabe21977e0cfb91db6a6d60cfff151d4d49a51e509d1e8403f1f2325885c4414190f91e9d6b468696ad637a3b556cc988888e59e39d542c9944c3ac3f801749c3b23b237c920da0a2d0c4774423dcf558f703d180ca0ca13a2e4ae38e930478f3490f19151686f3e56a3386654b302612643df6d7b46fe3422bb22b888c8d1d058704c9b19338f9cf709d72dbfb489b225ba04917d7c95ea0e59a9fb6d4f2a7be02c346b90c41f8d807e5307b5855d0b00cbb682fa6d79cf01e32bd2335293d8a0a6f78fcae658a58a718f1197da3a50b5a70a8e06717e56af376073fd1bc9982e330634b54d53d39d26519d646c279a582b4436a774fe33bde8f506782e7741bb978fe13d69b955a99851af37a07178346f762573820bf62463faed3454bacd4ac661e0b05d98d452fa2563f34c3dd2f70472c5b8c7089f77001ec618ebba4f74f2ee3693c5d4a1fd9fc218794779209d595a8351b8ff5aa3ba5feb3780ef5d967333e65a21baf4e92518614472a903f819ed871fa7eb4f2386183a8e9c8167af38dd35e01d8076590bff8c1f5c3587d1e5202e1d69470c3118d6abe08ff9e1ac6d40f96be5587b3ea5872e4114fe9f28baffe80657cd2186185c2da764f59c181a26c36695503fd95f0c31b4feaa35eb41c5c4d030e11130ba1c4c6da688c875dc05ae9a4379ad0ea68307543f48e9fecc03676d03bce65da271e8bee641e5ba5ed06b723d82d3f52d28473996d6d7847148b6cba71ff6202db6cf9e4099fdf967fc687eb305667d0dd60ea6c619059d7b75f3a7b676a284e65609ddeafad75e78f60fb794f0299e3d507b16e04694f29ee6525d1244ed61757ae4328cb6881613442df788acf7f997291713547a2bf81f0419da6e93a25852e3037dc43fb27c5a65620938705d596c7be363f927631d57891ec725f2c97a079adfcfff442d176ab688ca7f004c3c5983e5659d649ed54544c9eb134fd6607ce505d579e55cfd6f3e971d1ac5165649abd1c13f1305aa6b608a2fc1b27777d1fd7aefcf51585b85f9c900badeb2015883e1a5943d13b38be49e34000800b00108c0f6960d2ecd37d06c9f1550d3dfd2ca2af9a143e06e4a9ece644357654a9e32a6ed1ede616a952f73abc5336da1ed9460fbb8581e9138542192ee37b450fc29b1e4dbcfa61ef18a4109e973caa185e25696aefbd972b543623bfa1fcadfa7967bca8f7b121171b7e44f03a68f7359defce8bcafa0ec40a1a54a07ccfd5bfe7c6dae195b683b2578362896d7f1bf51717ef50f1392fd1eb8e9c3401f9146c1a11f29ec7e308ff8262f2fb29c61ef0f21696f40531cb3af5566cb8d47c47972ae1ab0564a8fb77bd28c377ac6f2e6cb5d4454f55f23f0c72c927242ef39442b5a59bebce8d30809a25f031d11c0279395121c37d7e9329901e0779785b55382d9a7dc6a326eb445b6ffe0631f0efc09585a51efb8d6ca2a593b269e64eb05a34394472e0431232d77e249aadee6738c35becbd8e2070e6835d976477436e82efad0b025edb8f60491eea20f8f0d7559fd546a4740e71c8865a437cb2a974620c74ca6d79e4e0c5bf32270f68e0ffffa0780fd6e0497d680a5bf7d23aa53a503ecbf90d14bffed316d96bc9968c6f540cefe23411f0edce4635055fdcf4465edb0bc9cad17623e70d545c6d0d5d2722d2f67d71f7d9eb1b58f1c30ad65db1fdf7460d77ffad07195a87b7c9a9656883eb937451d57f9332fc91524bd5d8b368cf97faf93dc33f0718b544c3244925982d50d22bb9f08e3fcbb61b845843ef5b12b0212fdf685c495124418cdaec7ddca1dab3dcd983653de74c6ab25b2e32981fd0f95c79cd32bf276d082744c5bec7724dac7a725e5529e58b97d5cddbb809931733ef9656b9be2199c44fbff85f95869bbb406a3609781173a7d18fd3380a00fd89e21a137a1be3c9260a4c716b08bbe549d1f02f6cd7056bdf6437996f06f91697d7998361d9b3ee3cf3117cbb490615a64842eaa43a1ea1a69b9124c9b8ecd07190bbdbe06adcab32626bd038b3f07d65ec9fde04876b72b62c5eee19c33e476b400a61dcf3de3e65653ccae7657fc6d326de63b76a671febb67447c3d229e01d3df76e66e8584eb85306d4896698bcb1ec831a6d2ac849ab7ba2bef91e23c7a99873126e9f9db85fd6e04f86b5dce19e230427dc9c348affeb70f662ff0c2a7e27ada791f8cf966e23314d3865e072c7b99701cd0c3186b3ef863b6f873807b87afe78f5960be16c8797aadf74bf18a937efd59886925efc38b403ca2946947801f28935bc601e08cc8daf58dcc03ecf208f062f6ae4e843f2b70b366b4e5969b3ca7ab13d7eb7f27bfe37d9bd903479a5dd6ca00a41e04f8c1efbaed3f612cf45e6a97cdcefb605ce04fa325ebb988c87b9fc81d37cbda0199ec41e684528d3351e9717c92bfbd8bf8ac80d2d37b8f0d7579276e12cbfc007cbf4096e71ffed407ace76658c0013c9990f5cb9c4545ec978e3acd5a7ec7cad17e33b151509e5429d38a635a5b5e79b15718dbf80f7e0549e673d915e085b6db74b48d889df7e1e45d897ed3ed7d4a316dbc527d4cabd922322ef07a4b6505726164994f8fd913b91db72cb96455ee5736233271f8671659bfcc5914306d265a2ba1e891684e39287faa4c2bb64b995cef737cba482acfa964c5887e9dad178c0e04ee16170af93e1b91942bf78a906e81a8e673e0c04d69bd4d7a60fa8403edd62842eff179d8cc7af12a07765ff161f3be78c5c9625a0e40877e1e8530dfefbe0c4bfa64de1254d70f623e047eadd0b172c8d97dc5878959a2d8c26ade27358530ad7805512ed7c3e4f39cf96273c34b8c49e5db838f81eef1e9825696d6a1297a1ccf5e699d9aec57845cc4e75dd94de0f164b6be26bd03a1d7d730f63e63932ff1317dec15c6c2bf3dccba2ae725b30c27effaa0fb3d7ff621ebfeae22b52bb3f68da9cfaf8dabcf1c90ca6f7aa1ed3659ef2b7f765f487e500ebbeef3bbffa47c35795a355fc64947e750fef1c96c4724ff65766b1fd1c656fedd396df1f52aaf4a678ba43ec34a245f5fe9990b4a1099726493ac7d24ea57f4851917f1b1089f3d508e744edd664cedf710b41a07a227949f1a3ada4654c81b11b93079aaec8536f1a9b8766b14cd077f2ce895fefd086ba5038def1676aa6cf4e11c357d26ff16b3d429b7e433fcc7f13ad976d64afed49429ce9f06c34c1481f91ac4370388e47893c45a1940e0d7362134d06c119d5d06dc37a5eb6b353e2c7ee080f739e5f64fcc12f50ee69797e5f98b09f58cd412985697a375e7cefb16f3e4681540cbbda91d63dacc274b99795829e6499d722a2e4f4a0bd20c64eac9cde0fd0ff91ced4ed8dfff503a2f9beb7497b5aff00f63e75a31d0769b36b688241b3a67b72b2a7d93e102ff068292a2f6eb89cea1c2be66b8b1c5f7175a582d0ae50636dff59dfc0d894cbdd4b4eb7f3847ed2bbc2359fbb69772992fb05bfbf8071ded2bfcaf16e572bcfe877364eddb76b0365e3ef7906fb713f676dde7e5277fe3a3f2eab0f0db1cb2b14dae18431203fcf7677395ce0975b16ca1316109ffb131275315f25b0bc92f7f6716d34048951c258f364bf8fdc4bc1586675532ee0e60a1214109bf1fa8a8e2622215bba8655e35a8bdc0c760cfc2c094f0d945c51589b683e2a7c4b0d6fb449428bd2d5bc2fca8ba41686195ac7d3bc7b0c5a4474af8fdc4821b12f179c8ca7bea99b5f2ea30ff0be525662d6101b8238292f9c0e9157ed79fccaf25917bc827e837b64abf815bc2e2f1ff01e7c125e6c297007b0000000049454e44ae426082</data> </image> </images> <connections> @@ -1330,8 +1277,6 @@ Montreal, Quebec H2T 1S6</p></string> <tabstop>codec1</tabstop> <tabstop>codec2</tabstop> <tabstop>codec3</tabstop> - <tabstop>codec4</tabstop> - <tabstop>codec5</tabstop> <tabstop>Tab_Preferences</tabstop> <tabstop>Tab_About</tabstop> <tabstop>Register</tabstop> diff --git a/src/gui/qt/configurationpanel.ui.h b/src/gui/qt/configurationpanel.ui.h index 4ca9ba90b2..f28ff03da7 100644 --- a/src/gui/qt/configurationpanel.ui.h +++ b/src/gui/qt/configurationpanel.ui.h @@ -77,8 +77,7 @@ void ConfigurationPanel::init() codec1->setCurrentText(QString(get_config_fields_str(AUDIO, CODEC1))); codec2->setCurrentText(QString(get_config_fields_str(AUDIO, CODEC2))); codec3->setCurrentText(QString(get_config_fields_str(AUDIO, CODEC3))); - codec4->setCurrentText(QString(get_config_fields_str(AUDIO, CODEC4))); - codec5->setCurrentText(QString(get_config_fields_str(AUDIO, CODEC5))); + ringsChoice->setCurrentText(QString(get_config_fields_str(AUDIO, RING_CHOICE))); // For preferences tab @@ -132,8 +131,7 @@ void ConfigurationPanel::saveSlot() Config::set("Audio", "Codecs.codec1", string(codec1->currentText().ascii())); Config::set("Audio", "Codecs.codec2", string(codec2->currentText().ascii())); Config::set("Audio", "Codecs.codec3", string(codec3->currentText().ascii())); - Config::set("Audio", "Codecs.codec4", string(codec4->currentText().ascii())); - Config::set("Audio", "Codecs.codec5", string(codec5->currentText().ascii())); + if (ringsChoice->currentText() != NULL) Config::set("Audio", "Rings.ringChoice", string(ringsChoice->currentText().ascii())); diff --git a/src/gui/qt/configurationpanelui.cpp b/src/gui/qt/configurationpanelui.cpp index 118928c752..02e8613e25 100644 --- a/src/gui/qt/configurationpanelui.cpp +++ b/src/gui/qt/configurationpanelui.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** Form implementation generated from reading ui file 'gui/qt/configurationpanel.ui' ** -** Created: Mon May 30 14:35:17 2005 +** Created: Thu Jun 2 11:14:54 2005 ** by: The User Interface Compiler ($Id$) ** ** WARNING! All changes made in this file will be lost! @@ -322,467 +322,417 @@ static const char* const image0_data[] = { static const unsigned char image1_data[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x30, - 0x08, 0x06, 0x00, 0x00, 0x00, 0x63, 0x57, 0xfa, 0xde, 0x00, 0x00, 0x15, - 0x75, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0xed, 0x5d, 0x7f, 0x6c, 0x53, - 0xd7, 0xbd, 0xff, 0x1c, 0xd4, 0x21, 0x07, 0xa5, 0xd5, 0x75, 0x45, 0xa7, - 0xeb, 0x48, 0xab, 0x6c, 0x34, 0xd0, 0x9c, 0xae, 0x68, 0x36, 0x65, 0x5a, - 0x9c, 0xb5, 0xaa, 0x6f, 0xd5, 0x6a, 0x38, 0xa4, 0x1a, 0x71, 0xfb, 0x24, - 0x92, 0x6c, 0x15, 0xb9, 0x40, 0xd5, 0x25, 0xdd, 0xb4, 0x97, 0xb0, 0xe9, - 0x75, 0x09, 0x15, 0x25, 0xdd, 0xf4, 0x0a, 0x2e, 0x6a, 0x9b, 0xac, 0x1a, - 0xe0, 0x20, 0xba, 0x38, 0x48, 0x0f, 0x0c, 0x4f, 0x90, 0x84, 0x27, 0xaa, - 0x5e, 0x57, 0xf4, 0xc5, 0x79, 0x2a, 0x2f, 0xf6, 0x44, 0x37, 0xbb, 0x2a, - 0x15, 0xb6, 0x60, 0xc2, 0x16, 0x45, 0xb1, 0x45, 0x23, 0x62, 0x45, 0x93, - 0xbe, 0xef, 0x8f, 0x1b, 0x5f, 0xfb, 0xda, 0xd7, 0x3f, 0xae, 0x03, 0x23, - 0x4f, 0xcd, 0xf9, 0xe7, 0x43, 0xb8, 0xe7, 0x7c, 0xcf, 0xf7, 0x9c, 0xfb, - 0x3d, 0x9f, 0xf3, 0x3d, 0xdf, 0x73, 0xee, 0x31, 0xae, 0x02, 0x38, 0x0a, - 0xe0, 0x6e, 0x21, 0x11, 0x11, 0x5d, 0x23, 0x22, 0x22, 0x9a, 0x5a, 0x44, - 0x5a, 0x20, 0xba, 0xdb, 0xf5, 0xac, 0xe0, 0x37, 0x17, 0xd9, 0x51, 0x00, - 0x02, 0x00, 0xa9, 0x06, 0x14, 0x89, 0x68, 0xe2, 0x4a, 0x02, 0x80, 0x09, - 0x03, 0x01, 0x09, 0xe1, 0xa4, 0xad, 0x6c, 0x09, 0xa7, 0xd9, 0x0d, 0xbb, - 0x29, 0x84, 0xfd, 0x4f, 0xdb, 0x31, 0xb6, 0x9a, 0xb1, 0x5a, 0xeb, 0x5d, - 0xc1, 0x6f, 0x36, 0xb2, 0xab, 0x35, 0x14, 0x9c, 0xbf, 0x49, 0x14, 0x4e, - 0x02, 0x3d, 0xe7, 0xfd, 0x48, 0xf3, 0x02, 0x10, 0x97, 0x00, 0xb3, 0x3e, - 0xe4, 0xac, 0x02, 0xda, 0x0c, 0x46, 0x78, 0x5b, 0x01, 0x2f, 0x5b, 0x31, - 0xe0, 0x15, 0xac, 0x1e, 0x75, 0x31, 0xad, 0x48, 0x44, 0xc2, 0x07, 0x12, - 0x02, 0xf1, 0xf2, 0x8c, 0xaa, 0x17, 0x9d, 0x66, 0x37, 0x7c, 0xdb, 0xe6, - 0x91, 0x79, 0x68, 0x0d, 0xbb, 0xdf, 0x1d, 0xb2, 0x82, 0xcb, 0x1f, 0x57, - 0x55, 0x93, 0xd1, 0xb2, 0x40, 0xc4, 0x7f, 0x41, 0xc4, 0xde, 0xf0, 0x23, - 0x80, 0x45, 0x83, 0x35, 0x0b, 0x77, 0x0d, 0x03, 0x71, 0x3f, 0x1a, 0xce, - 0x64, 0xe0, 0xbb, 0xf8, 0x37, 0xba, 0xdf, 0x1d, 0xb2, 0x82, 0xcb, 0x1f, - 0x2b, 0x32, 0xed, 0xfc, 0xcd, 0x59, 0xea, 0x3c, 0x63, 0x44, 0x38, 0xe9, - 0xff, 0xa7, 0xa8, 0x64, 0xe3, 0xc3, 0x08, 0xed, 0x16, 0x56, 0x5c, 0x86, - 0x15, 0x2c, 0x89, 0x65, 0x99, 0xd6, 0x72, 0x93, 0xa8, 0xf9, 0x63, 0xc8, - 0x06, 0x6b, 0x5e, 0x7c, 0x72, 0x8f, 0x31, 0x6c, 0xb0, 0xc1, 0xf8, 0x96, - 0x1f, 0x22, 0x11, 0x2d, 0x87, 0x0e, 0x5a, 0xc1, 0xe5, 0x87, 0x25, 0x99, - 0x76, 0xfe, 0xe6, 0x2c, 0x35, 0x1f, 0x03, 0xd2, 0x19, 0x9d, 0x22, 0xd7, - 0x06, 0x81, 0x07, 0x5a, 0x94, 0xbf, 0x5d, 0x8f, 0x84, 0x30, 0xfa, 0x13, - 0x3b, 0xa4, 0x78, 0x02, 0x06, 0x83, 0x09, 0x5b, 0xff, 0x5c, 0x1d, 0x63, - 0x73, 0x06, 0x09, 0xa9, 0xdf, 0xb8, 0x97, 0xc4, 0xb8, 0x22, 0x11, 0x0d, - 0x1f, 0xf6, 0x22, 0xf4, 0xbf, 0x41, 0x14, 0x26, 0xeb, 0xf7, 0xac, 0xe8, - 0x7e, 0xb6, 0x1b, 0xe9, 0xb5, 0x69, 0x64, 0x1a, 0x1a, 0xfe, 0x5f, 0xf8, - 0xd2, 0x22, 0x11, 0x4d, 0x9c, 0x9b, 0x40, 0xcb, 0x8f, 0x5b, 0xe0, 0x7d, - 0xf8, 0xee, 0xcc, 0x44, 0xfc, 0xed, 0x3b, 0x34, 0x7c, 0x64, 0x18, 0xd1, - 0xcf, 0xa3, 0x88, 0x5e, 0x89, 0xc1, 0xba, 0xde, 0x82, 0xa1, 0x57, 0x87, - 0x30, 0xb6, 0x71, 0x8d, 0x6e, 0xf9, 0xf7, 0x42, 0x3f, 0x2d, 0xd4, 0x8c, - 0x1e, 0x58, 0x6e, 0x12, 0x19, 0x3f, 0x4e, 0x21, 0x1d, 0x95, 0xaa, 0x8b, - 0x06, 0x24, 0x25, 0xcc, 0xfc, 0xcc, 0x0d, 0x7b, 0x3d, 0x80, 0x07, 0x8b, - 0xec, 0x43, 0x49, 0xc1, 0x18, 0xd0, 0xfc, 0x49, 0xaa, 0xea, 0x28, 0x03, - 0x97, 0xac, 0xcd, 0x70, 0x2d, 0xb7, 0x89, 0xa4, 0x33, 0x41, 0xf4, 0xbc, - 0xd7, 0x03, 0x27, 0x04, 0x04, 0x20, 0x29, 0x3a, 0x68, 0xfd, 0x6d, 0x6c, - 0xe5, 0x30, 0xb8, 0xb7, 0x7f, 0xd9, 0xbb, 0x24, 0xde, 0x7d, 0xfb, 0x29, - 0x75, 0x2e, 0x8d, 0x00, 0x24, 0x44, 0x2e, 0x84, 0xee, 0x8a, 0x61, 0x18, - 0xde, 0x1c, 0xa5, 0x37, 0xcf, 0x78, 0x54, 0xfd, 0x01, 0x27, 0xd0, 0x77, - 0xc0, 0xa3, 0x7b, 0x20, 0xdf, 0x0b, 0xfd, 0xb4, 0xb0, 0x88, 0x69, 0xf9, - 0x05, 0xa2, 0x86, 0x43, 0x29, 0x5d, 0x0c, 0x3b, 0xbb, 0xc7, 0x0d, 0x63, - 0x1d, 0xca, 0x26, 0xf1, 0x7c, 0x08, 0x23, 0x97, 0x2c, 0xba, 0x55, 0xac, - 0x85, 0x71, 0x83, 0xbb, 0xba, 0x68, 0x3a, 0x1c, 0x56, 0xea, 0xe6, 0x79, - 0x13, 0xdc, 0xad, 0x6d, 0xe8, 0xde, 0x22, 0xc2, 0xf7, 0x89, 0x0f, 0xd6, - 0xa4, 0x15, 0x7d, 0x81, 0x01, 0x24, 0x93, 0x09, 0x25, 0xcf, 0xe8, 0xe1, - 0xa3, 0x30, 0xda, 0x37, 0x2d, 0x6b, 0xc6, 0x15, 0x89, 0xc8, 0x37, 0xe6, - 0x43, 0xc7, 0x93, 0x1d, 0xf0, 0x3e, 0xba, 0x74, 0x83, 0x10, 0xaf, 0x11, - 0x35, 0xb6, 0xd9, 0x55, 0xef, 0xa9, 0xc9, 0x66, 0x83, 0xf7, 0xb0, 0xb7, - 0xa6, 0x01, 0x7c, 0xb7, 0xf5, 0xab, 0x9a, 0x69, 0x7d, 0x17, 0x89, 0x02, - 0x01, 0x7f, 0xf5, 0x71, 0xd7, 0xcd, 0x2e, 0xd0, 0x96, 0xf2, 0x16, 0x6b, - 0x1f, 0x0b, 0x22, 0xfc, 0x0f, 0x6b, 0x4d, 0xf1, 0x5c, 0x98, 0x05, 0x38, - 0x11, 0x86, 0xf7, 0xa5, 0x67, 0xaa, 0x32, 0x28, 0x71, 0x81, 0xa8, 0xd1, - 0x61, 0x57, 0x18, 0x75, 0xff, 0x8e, 0xfd, 0x48, 0x77, 0x6f, 0xd5, 0xec, - 0x40, 0xcb, 0x17, 0x44, 0x89, 0x5b, 0x09, 0x84, 0x6e, 0x85, 0xd0, 0xf8, - 0xfc, 0xd6, 0x92, 0xf2, 0x2d, 0x5f, 0x10, 0x61, 0xfd, 0xd2, 0xe2, 0xc9, - 0x22, 0x11, 0x95, 0x2b, 0x2f, 0xce, 0x12, 0xd5, 0xca, 0x4c, 0x96, 0x1b, - 0x44, 0x30, 0x40, 0x17, 0xb3, 0x89, 0x0b, 0x44, 0x8e, 0xe7, 0x04, 0xa4, - 0xe7, 0xd2, 0x00, 0x72, 0x33, 0xd0, 0xe8, 0x6b, 0x47, 0x11, 0x6e, 0xdb, - 0x54, 0xb2, 0xbf, 0x62, 0x1b, 0x98, 0xee, 0x81, 0xad, 0x57, 0x3f, 0xcb, - 0x0d, 0x22, 0x98, 0x4a, 0xf7, 0xb7, 0x8a, 0x69, 0x9b, 0x6e, 0x12, 0x3d, - 0xf6, 0xbe, 0xbe, 0x28, 0x41, 0xd7, 0xe6, 0x18, 0xbc, 0x5b, 0xd4, 0xa3, - 0x35, 0x3f, 0xd5, 0xca, 0xb0, 0x85, 0x38, 0xba, 0x2d, 0x0d, 0xc7, 0xc6, - 0x75, 0x15, 0x3b, 0x2c, 0x15, 0x9a, 0xa1, 0xce, 0xdd, 0x3b, 0x95, 0xfa, - 0x9d, 0x4e, 0x41, 0xf7, 0x54, 0x27, 0x5e, 0x23, 0x72, 0xff, 0xb6, 0x03, - 0xd1, 0x2b, 0x51, 0xcd, 0x36, 0x39, 0x9d, 0x02, 0xfa, 0x76, 0x75, 0x03, - 0x1b, 0xd6, 0xb1, 0x8e, 0xa7, 0x9d, 0x94, 0x9e, 0x4b, 0x83, 0xab, 0xe7, - 0x10, 0xfc, 0x40, 0x2a, 0x62, 0x98, 0xd8, 0xc5, 0x29, 0xea, 0xdf, 0xdb, - 0x8f, 0xf4, 0x5c, 0x1a, 0xd6, 0xf5, 0x56, 0xb8, 0x4e, 0x8c, 0xb1, 0xac, - 0x9e, 0xde, 0x13, 0x09, 0x84, 0x2f, 0x79, 0x14, 0xc3, 0xc9, 0x26, 0xeb, - 0x7a, 0x2b, 0x9a, 0x9e, 0xb0, 0xa1, 0xef, 0x5f, 0xfb, 0x54, 0x2f, 0xce, - 0xe6, 0x99, 0xa1, 0xce, 0x13, 0x72, 0xdb, 0x86, 0xde, 0x1e, 0x82, 0xe5, - 0xa9, 0x66, 0x36, 0xf9, 0xa7, 0xa3, 0x34, 0x7c, 0x64, 0x58, 0x29, 0xcb, - 0xf3, 0x26, 0x65, 0x06, 0xf9, 0xe8, 0xd7, 0x13, 0x98, 0xec, 0x68, 0xd0, - 0x7c, 0xf1, 0x59, 0xbd, 0xb5, 0xd2, 0xcc, 0xc8, 0x14, 0xc6, 0x36, 0xae, - 0x61, 0xed, 0x97, 0xef, 0x50, 0xcb, 0x6b, 0x2f, 0xa8, 0x66, 0xa4, 0x6c, - 0xe2, 0xea, 0x39, 0x0c, 0x3a, 0x07, 0x61, 0xdd, 0x65, 0x51, 0xd6, 0x04, - 0xd5, 0xe8, 0xc7, 0xd5, 0x73, 0x4a, 0x7b, 0xb3, 0xfa, 0x65, 0xd7, 0x1e, - 0xfe, 0x73, 0xa7, 0x8b, 0xea, 0xe2, 0x79, 0x13, 0x86, 0x5a, 0x87, 0x60, - 0xd9, 0xce, 0x23, 0xb9, 0x18, 0xc7, 0x57, 0xa2, 0x07, 0x22, 0x11, 0x35, - 0x1f, 0xd3, 0x1f, 0x25, 0x10, 0xcc, 0xa5, 0x0d, 0x36, 0x18, 0x03, 0x46, - 0xbe, 0xb2, 0xe8, 0x92, 0x57, 0x0a, 0x7b, 0x3e, 0xe7, 0x60, 0x59, 0xa0, - 0x8a, 0x71, 0x5c, 0xbb, 0xad, 0x40, 0x9f, 0x00, 0x20, 0x6e, 0x75, 0x91, - 0xed, 0xf4, 0x0c, 0xc5, 0x2e, 0x4e, 0x91, 0x38, 0x5b, 0x39, 0x2a, 0xd1, - 0xd8, 0x66, 0x47, 0xf4, 0x4a, 0x14, 0x5c, 0x3d, 0x87, 0x99, 0x91, 0x29, - 0x44, 0xc6, 0x42, 0x88, 0x5c, 0x08, 0xc1, 0xe9, 0x14, 0x64, 0x46, 0x0a, - 0x48, 0xe8, 0xd8, 0x2d, 0xc2, 0x72, 0x9b, 0x48, 0x80, 0x00, 0x00, 0x48, - 0xcf, 0xa5, 0x21, 0xfc, 0xa2, 0xa5, 0x48, 0x5e, 0xf0, 0xad, 0xa0, 0xf2, - 0x92, 0x52, 0x5f, 0xa7, 0x21, 0x00, 0xf0, 0x7b, 0x0e, 0x50, 0xe7, 0xee, - 0x9d, 0x08, 0x04, 0x06, 0x60, 0x9b, 0xb3, 0x83, 0xe7, 0x4d, 0xf8, 0xdd, - 0xb6, 0x5e, 0x34, 0xd9, 0x6c, 0x68, 0xab, 0x6f, 0x43, 0xf4, 0x4a, 0x14, - 0x23, 0x27, 0xc6, 0xd0, 0xb8, 0xd9, 0x8e, 0xf6, 0xcb, 0x77, 0x14, 0x7d, - 0x3b, 0x4f, 0xec, 0x94, 0x7d, 0x4e, 0x00, 0x7c, 0xc6, 0x04, 0x09, 0x00, - 0x77, 0xcb, 0xa0, 0x6a, 0xae, 0x35, 0x69, 0x55, 0xfe, 0x3d, 0xfc, 0xa5, - 0xb7, 0x64, 0x3b, 0xfd, 0xbf, 0xf7, 0x01, 0x80, 0x22, 0x2f, 0x9b, 0xf6, - 0xef, 0xd8, 0x8f, 0x3a, 0x73, 0x1d, 0x04, 0x00, 0x9b, 0xba, 0x9a, 0x61, - 0x4d, 0x5a, 0xc1, 0xf3, 0x26, 0xcc, 0x8c, 0x4c, 0x61, 0xf4, 0xf0, 0x51, - 0xa5, 0x1f, 0xd2, 0x73, 0x69, 0xf4, 0x9c, 0xeb, 0x81, 0x77, 0xb7, 0x0f, - 0x7a, 0xf4, 0xb3, 0xcd, 0xe5, 0xde, 0xcf, 0xf0, 0x97, 0x5e, 0x99, 0xf1, - 0x9d, 0x02, 0x86, 0x8f, 0x0c, 0x23, 0x99, 0x4c, 0xa0, 0x9d, 0x6f, 0x47, - 0x5b, 0x6b, 0x1b, 0x46, 0x5f, 0x3b, 0x0a, 0xeb, 0x7a, 0x2b, 0xac, 0x49, - 0x2b, 0x5e, 0x38, 0xe2, 0xc6, 0x33, 0xcf, 0xb7, 0xc0, 0xf2, 0x85, 0xfc, - 0xfe, 0x15, 0xa6, 0x1d, 0x3c, 0x3b, 0x43, 0x23, 0xe1, 0x1a, 0x18, 0x91, - 0x0f, 0x83, 0x76, 0xab, 0x1b, 0x9e, 0x4d, 0x62, 0x14, 0x18, 0x39, 0x79, - 0xf7, 0xe2, 0xbb, 0xfb, 0x77, 0xb8, 0x61, 0xaa, 0xc2, 0x57, 0x6a, 0xbf, - 0x7c, 0x87, 0x36, 0x75, 0x35, 0x6b, 0xea, 0x94, 0x4d, 0x5c, 0x3d, 0x07, - 0xeb, 0x7a, 0x0b, 0x84, 0xa7, 0x05, 0x74, 0xb4, 0x77, 0xa8, 0x18, 0x4d, - 0x5c, 0x20, 0x0a, 0xfd, 0x35, 0xa4, 0xe9, 0xe3, 0xb6, 0x3c, 0x61, 0xa3, - 0xac, 0x8c, 0xc8, 0x85, 0x10, 0x86, 0x4f, 0x7a, 0x91, 0xcf, 0x24, 0x1f, - 0x9d, 0x9d, 0x50, 0x98, 0x27, 0xeb, 0xaa, 0x64, 0xd3, 0xcc, 0xc8, 0x14, - 0xa4, 0xb8, 0x84, 0x3d, 0x6f, 0x0c, 0x28, 0x3a, 0x74, 0xef, 0x12, 0xe1, - 0xe8, 0xe8, 0x54, 0xd5, 0xe3, 0xf2, 0xdd, 0xa0, 0x67, 0x0e, 0xb5, 0x28, - 0xe5, 0x22, 0xa7, 0x43, 0xf0, 0x3e, 0xca, 0x98, 0x27, 0xaf, 0xee, 0xee, - 0x5d, 0xdd, 0x70, 0xbd, 0xbc, 0x93, 0x0d, 0x16, 0xf8, 0xef, 0x80, 0xcc, - 0xd4, 0x5d, 0xdb, 0xdb, 0xd1, 0xf8, 0xfc, 0x56, 0x16, 0xf4, 0x8d, 0x52, - 0xf0, 0x2f, 0x1c, 0x32, 0xe9, 0xd3, 0x00, 0x00, 0xfb, 0x13, 0x0e, 0x74, - 0xef, 0x16, 0xe1, 0x65, 0x8c, 0x15, 0xd6, 0xd3, 0xd6, 0xda, 0x06, 0xcb, - 0xeb, 0x03, 0x15, 0xfb, 0x41, 0x24, 0xa2, 0xc6, 0xcd, 0xb9, 0x76, 0x65, - 0x17, 0x5d, 0x7a, 0xf5, 0x6b, 0x69, 0x6d, 0x81, 0xb8, 0x5b, 0x44, 0xf6, - 0xb9, 0xd3, 0x29, 0xc0, 0x7e, 0xc0, 0xa3, 0x7a, 0xbf, 0xde, 0x7d, 0xfb, - 0xe9, 0xf4, 0x39, 0x59, 0xf7, 0x26, 0x9b, 0x0d, 0x8e, 0x23, 0x23, 0x6c, - 0x95, 0x00, 0x79, 0xc7, 0xeb, 0x74, 0xa6, 0x46, 0x46, 0x34, 0xd8, 0x10, - 0xf9, 0xaa, 0xc8, 0x26, 0x00, 0x00, 0xde, 0xb5, 0xb8, 0xab, 0x71, 0x5c, - 0xcf, 0x89, 0xea, 0xe2, 0xb7, 0x63, 0x1b, 0xd7, 0xb0, 0xc8, 0xa5, 0x10, - 0xba, 0xb6, 0xb7, 0xa3, 0xfb, 0xd9, 0x6e, 0xb9, 0x43, 0x0a, 0x18, 0xc5, - 0x36, 0x67, 0xc7, 0x74, 0x38, 0x8c, 0x37, 0x0f, 0x79, 0xd0, 0xb8, 0xd9, - 0x8e, 0xa6, 0x0b, 0x57, 0x15, 0xb9, 0xde, 0xd5, 0x8c, 0xe5, 0xbf, 0xa8, - 0x54, 0x68, 0x86, 0x5c, 0xc1, 0x1b, 0x24, 0x6e, 0x75, 0x29, 0x2f, 0xc5, - 0x09, 0x01, 0x88, 0x03, 0xdd, 0xbb, 0x45, 0x70, 0xf5, 0x9c, 0x22, 0x3f, - 0xf5, 0xd7, 0x8c, 0xa2, 0x47, 0xff, 0x1f, 0x06, 0x95, 0xfa, 0xda, 0xf9, - 0x76, 0x8c, 0x6d, 0x5c, 0xc3, 0x3c, 0x87, 0xa3, 0x4a, 0x79, 0x2d, 0x83, - 0x15, 0x00, 0x4c, 0x76, 0x34, 0xb0, 0xa1, 0x57, 0x87, 0x94, 0xb2, 0xdd, - 0xef, 0xf5, 0x15, 0x68, 0x0f, 0x38, 0x2d, 0x82, 0x9c, 0xdf, 0x2c, 0xa8, - 0xda, 0x77, 0xea, 0xf7, 0x7e, 0xb8, 0x4e, 0x8c, 0xb1, 0xac, 0x8f, 0xfe, - 0xe6, 0x21, 0x0f, 0x02, 0x81, 0x01, 0x18, 0xc2, 0x46, 0x4c, 0x87, 0xc3, - 0x18, 0x3e, 0x32, 0x0c, 0xdf, 0x98, 0x0f, 0x02, 0x00, 0x93, 0xd5, 0x94, - 0x93, 0x07, 0x01, 0x83, 0xad, 0xfd, 0x2a, 0x3d, 0x0a, 0xfb, 0xc1, 0x12, - 0x22, 0x72, 0x05, 0x6f, 0x90, 0xd0, 0xda, 0xa2, 0xea, 0xcf, 0x50, 0x3c, - 0x54, 0x93, 0x7e, 0xb8, 0x82, 0x9c, 0xc1, 0x42, 0x40, 0xf2, 0xef, 0x09, - 0x88, 0xd7, 0x88, 0x52, 0xa1, 0x19, 0x12, 0x67, 0x89, 0x2c, 0x17, 0x89, - 0x4c, 0x19, 0x93, 0xf2, 0x7c, 0x3a, 0x1c, 0x86, 0x48, 0x44, 0x0f, 0x48, - 0x00, 0x9a, 0xd2, 0x90, 0xc3, 0x5b, 0x10, 0xe4, 0xc5, 0x8f, 0x4e, 0xec, - 0xfc, 0xd0, 0x8d, 0x50, 0x3b, 0x8a, 0xd3, 0x23, 0xc0, 0x81, 0xf5, 0x69, - 0xec, 0x89, 0xd7, 0x26, 0xb7, 0x10, 0xd3, 0x10, 0xe0, 0xfb, 0x2c, 0x56, - 0x15, 0x2f, 0x7b, 0x19, 0x63, 0xee, 0xc5, 0xbf, 0x27, 0x00, 0x18, 0x6e, - 0x4c, 0xd0, 0xb0, 0xe1, 0x20, 0xa4, 0xbf, 0x06, 0xc1, 0x47, 0x4d, 0x18, - 0xf8, 0xb8, 0x1f, 0xb8, 0x92, 0x53, 0xf5, 0x85, 0xd7, 0xdc, 0x88, 0x2c, - 0x10, 0x79, 0x57, 0x33, 0xd6, 0x7e, 0xf9, 0x0e, 0xf5, 0xfd, 0x79, 0x00, - 0xe1, 0x4b, 0x21, 0x78, 0xe6, 0xd2, 0x40, 0x9e, 0x8f, 0x9c, 0x4d, 0x01, - 0x48, 0x80, 0x59, 0xae, 0xa7, 0xcd, 0x73, 0x80, 0x46, 0x4e, 0x8c, 0x01, - 0x00, 0x76, 0xfe, 0x5e, 0x44, 0x90, 0x88, 0x62, 0x57, 0x62, 0x90, 0x76, - 0x8b, 0x4a, 0x7e, 0xdb, 0x6e, 0x2b, 0x1a, 0xc7, 0x01, 0x4f, 0x72, 0x4c, - 0x29, 0x3f, 0xdc, 0x7e, 0x10, 0xde, 0x8e, 0x4e, 0x4d, 0xfd, 0x63, 0x96, - 0x5c, 0x5d, 0xe1, 0x4b, 0x21, 0x48, 0x85, 0xf5, 0xc7, 0x24, 0xb8, 0x00, - 0x0c, 0xc6, 0xa5, 0x9c, 0x3e, 0x00, 0xa6, 0x9f, 0x5b, 0xa7, 0xf6, 0xa9, - 0x5b, 0xdb, 0x90, 0xf8, 0x7b, 0x0c, 0x19, 0xa4, 0xd0, 0x04, 0x1b, 0x0c, - 0x9c, 0x51, 0x9e, 0x59, 0x3a, 0x3a, 0x21, 0x9a, 0x8b, 0xdb, 0x53, 0x38, - 0x63, 0xa9, 0xfb, 0x21, 0xc7, 0xae, 0x49, 0xe4, 0x7c, 0x4f, 0xbb, 0xd9, - 0x0e, 0x6f, 0x0d, 0xfa, 0x89, 0x6b, 0x0b, 0xea, 0xbf, 0x22, 0xbb, 0x66, - 0x5a, 0x29, 0x00, 0x09, 0x5c, 0x3d, 0x87, 0xf9, 0xaf, 0xe7, 0xf1, 0x80, - 0x00, 0xc0, 0x7d, 0x06, 0x35, 0xad, 0xea, 0xb3, 0x18, 0xfe, 0xd2, 0x0f, - 0xc0, 0xad, 0x59, 0x59, 0x5f, 0x93, 0xdc, 0xfb, 0x7b, 0xae, 0xd4, 0x2e, - 0x3f, 0x1f, 0xc3, 0x49, 0x37, 0x32, 0x28, 0x6f, 0xb0, 0x9a, 0xd8, 0xd0, - 0xc0, 0xbc, 0x79, 0x7f, 0x1f, 0x04, 0x10, 0x39, 0x3b, 0x4e, 0x93, 0x6f, - 0x04, 0x94, 0x0e, 0x1d, 0x3e, 0xe6, 0x85, 0xf5, 0xf8, 0x94, 0xe2, 0x5a, - 0x70, 0xf5, 0x1c, 0x3e, 0x7a, 0x77, 0x02, 0x26, 0xb3, 0x09, 0x30, 0x01, - 0xbe, 0x31, 0x1f, 0x82, 0x87, 0xc2, 0x4a, 0xfe, 0x2c, 0xc3, 0x58, 0xb6, - 0xf7, 0x21, 0x6b, 0xb4, 0xb6, 0x39, 0x3b, 0xf2, 0xa7, 0x4e, 0x27, 0x04, - 0x44, 0xf9, 0xa8, 0x12, 0x9d, 0xc8, 0x8f, 0x13, 0x87, 0xc2, 0xa1, 0xd2, - 0x2e, 0x0e, 0x67, 0xcb, 0x95, 0xaf, 0x8f, 0x42, 0x00, 0xe0, 0xc9, 0x2b, - 0x9f, 0xcf, 0x64, 0xf9, 0xd3, 0x6f, 0xa1, 0x1c, 0xf1, 0xf5, 0x81, 0x22, - 0x26, 0xf7, 0x1e, 0xf0, 0x40, 0x58, 0xd4, 0x5f, 0xa5, 0x4f, 0x3c, 0xa7, - 0x8f, 0xe1, 0xcd, 0x51, 0xda, 0xd4, 0xd5, 0x0c, 0x27, 0x04, 0x18, 0xf8, - 0x3a, 0xcc, 0xbc, 0x3b, 0x81, 0xba, 0xb5, 0x75, 0x4a, 0x3f, 0xbc, 0x79, - 0xc8, 0xa3, 0xe8, 0x87, 0x38, 0x6a, 0xd2, 0xaf, 0xb0, 0xfe, 0xb6, 0xd6, - 0x36, 0x0c, 0xbe, 0xda, 0x5f, 0x36, 0xca, 0x90, 0x7c, 0x68, 0x0d, 0x56, - 0x19, 0x6e, 0xdf, 0xa1, 0x70, 0x32, 0xb5, 0x64, 0x26, 0xf4, 0x47, 0x8b, - 0x57, 0x98, 0xd9, 0xd4, 0xd7, 0x04, 0x9c, 0xda, 0x9c, 0x01, 0x0c, 0x4b, - 0x67, 0x5c, 0xcf, 0x74, 0x65, 0x17, 0x41, 0x5c, 0x58, 0x9c, 0x62, 0x2a, - 0xe4, 0x6b, 0xf9, 0x71, 0x8b, 0x6a, 0xa3, 0x61, 0x7e, 0x2e, 0x85, 0x9e, - 0xf7, 0x7a, 0x00, 0xc8, 0x06, 0x1b, 0x0c, 0x48, 0x98, 0x74, 0x34, 0xb0, - 0x58, 0x03, 0x63, 0x5e, 0xc6, 0x98, 0xa3, 0xa3, 0x93, 0x45, 0xf9, 0x5c, - 0x44, 0xc1, 0x6e, 0xb6, 0x43, 0x02, 0x10, 0x6b, 0x60, 0xac, 0xad, 0xb5, - 0x0d, 0x00, 0x54, 0xf2, 0xb2, 0x7f, 0x0f, 0xb5, 0x0e, 0x29, 0xf5, 0x66, - 0x6c, 0x29, 0xe5, 0x99, 0xf7, 0xc4, 0x58, 0xc9, 0x81, 0xd6, 0xf9, 0x87, - 0x9d, 0x4a, 0xf9, 0xfe, 0xcd, 0xbf, 0x53, 0xa4, 0x66, 0xe5, 0x07, 0x62, - 0x92, 0x9c, 0x3f, 0xae, 0xae, 0x4f, 0xcf, 0x40, 0xb6, 0x9b, 0xed, 0x2a, - 0x7d, 0xb3, 0xed, 0x11, 0xaf, 0x91, 0xb2, 0xe1, 0x10, 0xae, 0x0f, 0x41, - 0x3a, 0x37, 0x81, 0xb1, 0x8d, 0x6b, 0x94, 0x7e, 0xe8, 0x68, 0xef, 0x50, - 0xb5, 0x2f, 0xcb, 0xd0, 0x7a, 0xf5, 0xb3, 0xdb, 0xd4, 0xf5, 0x0f, 0xee, - 0x28, 0x6d, 0xb0, 0x86, 0x1b, 0x37, 0x94, 0x45, 0xf8, 0xaa, 0x54, 0xa6, - 0x0e, 0x4b, 0xf6, 0x39, 0xd7, 0x06, 0xe1, 0xce, 0xf3, 0x8f, 0xb4, 0x92, - 0xdb, 0x6a, 0x02, 0xbd, 0x62, 0xc4, 0xe8, 0x8b, 0xee, 0x25, 0xd7, 0xe7, - 0xfb, 0xac, 0xbc, 0xc1, 0x36, 0x3a, 0xec, 0xf0, 0xee, 0x96, 0x57, 0xdf, - 0xdc, 0xf0, 0x38, 0x05, 0x7d, 0xa3, 0xb2, 0x8f, 0x74, 0x9b, 0x48, 0x5c, - 0x20, 0x8a, 0x5d, 0x9c, 0x22, 0xcb, 0xf1, 0x29, 0x6a, 0x7c, 0x2e, 0xc7, - 0x88, 0xed, 0x7c, 0x3b, 0xfa, 0x36, 0xf7, 0x29, 0x7f, 0xdb, 0xe6, 0xec, - 0x40, 0x58, 0xbd, 0xf8, 0x38, 0xb8, 0xa7, 0x97, 0xb2, 0x21, 0x99, 0x7c, - 0x86, 0x91, 0x00, 0x0c, 0xee, 0xed, 0x57, 0xb5, 0x37, 0xeb, 0xc3, 0x71, - 0xf5, 0x1c, 0x1a, 0xb7, 0x5b, 0x94, 0x7c, 0xde, 0x7f, 0xf7, 0x2a, 0xcf, - 0x03, 0x01, 0x09, 0xdc, 0xf0, 0x38, 0x65, 0x57, 0xc5, 0x59, 0x83, 0xe9, - 0xdb, 0xde, 0x4e, 0xfc, 0x15, 0x93, 0x52, 0x5e, 0xd8, 0xe5, 0x58, 0x94, - 0x96, 0x27, 0xbf, 0x84, 0xcf, 0xa8, 0x67, 0x06, 0x42, 0xbc, 0x40, 0xdf, - 0xc5, 0xf6, 0x4c, 0xfc, 0x65, 0x42, 0xed, 0xb3, 0xe6, 0xcd, 0x08, 0x22, - 0x11, 0xb9, 0xdb, 0x3b, 0x6a, 0xf6, 0x69, 0x55, 0x8c, 0xcf, 0x18, 0x1b, - 0x7d, 0xed, 0xa8, 0xf2, 0xdc, 0xf1, 0x73, 0x41, 0x15, 0x2d, 0xb1, 0xdc, - 0x26, 0x6a, 0xba, 0x70, 0x95, 0x3a, 0x9e, 0x76, 0xd2, 0xe0, 0xf3, 0x9e, - 0x5c, 0xf4, 0xa0, 0xab, 0xd6, 0xa8, 0x41, 0x16, 0xd7, 0x06, 0x41, 0xbf, - 0xc8, 0xad, 0x40, 0xab, 0x4d, 0xec, 0xb0, 0x04, 0x54, 0xf8, 0xd2, 0xa1, - 0x14, 0xf6, 0x6e, 0x77, 0xc3, 0xba, 0x41, 0x7b, 0x44, 0xf2, 0xb7, 0xef, - 0x50, 0xe7, 0xcb, 0x3b, 0x4b, 0xc6, 0x58, 0xb5, 0x92, 0x75, 0xbd, 0x15, - 0x07, 0xf7, 0x0d, 0xc2, 0xb2, 0xde, 0x02, 0x77, 0xbb, 0x3a, 0x3e, 0xcb, - 0xf3, 0x26, 0x64, 0xe6, 0xe6, 0x8b, 0x62, 0xa9, 0x00, 0x8a, 0xb6, 0x2a, - 0x2d, 0xfb, 0xa6, 0xa8, 0xe7, 0x5c, 0x8f, 0x2a, 0x4f, 0x76, 0x15, 0xad, - 0x1a, 0x58, 0xd7, 0x88, 0x84, 0x5f, 0xb4, 0x68, 0xc6, 0x3f, 0xf3, 0x13, - 0xcf, 0x9b, 0xe0, 0x7d, 0x7b, 0x08, 0xd8, 0x20, 0xc7, 0xa7, 0xbd, 0x79, - 0xb1, 0x55, 0xad, 0xd5, 0x39, 0xcf, 0x9b, 0xd0, 0x31, 0x3e, 0x59, 0xfd, - 0x06, 0x43, 0x61, 0x14, 0x20, 0x18, 0x82, 0x77, 0x35, 0x63, 0x22, 0xc9, - 0x61, 0xa8, 0xfc, 0x36, 0x57, 0xd3, 0x0f, 0xbe, 0xad, 0x2e, 0x65, 0x50, - 0x6b, 0xe9, 0xc7, 0xd5, 0x73, 0x10, 0x3f, 0x0e, 0x14, 0xe9, 0x97, 0xca, - 0x5b, 0x13, 0x94, 0x4a, 0xd6, 0xf5, 0x56, 0xf8, 0xc7, 0x7c, 0xf0, 0x32, - 0xc6, 0xd8, 0xfe, 0x8b, 0x44, 0x03, 0x7a, 0x76, 0xc0, 0xf2, 0xd0, 0xf5, - 0x60, 0x0c, 0x13, 0xdb, 0x4a, 0xc7, 0x69, 0x2b, 0xa5, 0xbe, 0x40, 0x04, - 0x9e, 0xeb, 0xa6, 0x1a, 0x76, 0xc8, 0x8c, 0xf0, 0xbe, 0x54, 0x7e, 0x67, - 0x46, 0xbc, 0x46, 0x74, 0xf0, 0xe4, 0x41, 0x98, 0x32, 0x26, 0x14, 0xee, - 0xad, 0x07, 0x20, 0xa1, 0xfb, 0xd9, 0x6e, 0x24, 0x0c, 0x09, 0xfc, 0x6e, - 0x5b, 0xaf, 0xea, 0x70, 0x48, 0x76, 0x2b, 0x12, 0x71, 0x79, 0x6a, 0x13, - 0xcc, 0x02, 0x82, 0xe9, 0x30, 0xfa, 0xb7, 0xf5, 0x22, 0x61, 0x48, 0xc0, - 0x70, 0xcb, 0x88, 0x40, 0x4c, 0x42, 0xdb, 0xe3, 0x2e, 0x98, 0xbe, 0x6f, - 0x42, 0xec, 0xa1, 0x9c, 0x1e, 0xd9, 0x33, 0x0f, 0xbe, 0xff, 0xf6, 0x42, - 0x30, 0x0b, 0x48, 0x18, 0x12, 0x70, 0xf7, 0xee, 0x29, 0xa9, 0x67, 0xe4, - 0xec, 0x38, 0xd5, 0xa5, 0x8c, 0x4a, 0xfe, 0x6c, 0x7d, 0x09, 0x43, 0x02, - 0x7d, 0x2f, 0xf6, 0x15, 0x6d, 0x54, 0x44, 0xce, 0x8e, 0x53, 0xfa, 0xb3, - 0x34, 0x82, 0xe9, 0x30, 0x86, 0xdf, 0x3a, 0x08, 0x2f, 0x63, 0x4c, 0x5c, - 0x20, 0x12, 0xbb, 0x45, 0x08, 0x66, 0x01, 0xa6, 0x27, 0x2d, 0xb0, 0x3c, - 0xd5, 0xac, 0x7b, 0x23, 0x65, 0xf8, 0xbc, 0x17, 0x6d, 0x8f, 0xbb, 0x30, - 0xe9, 0x68, 0x50, 0xf5, 0xc3, 0xf0, 0x61, 0x2f, 0xb8, 0x5b, 0x06, 0x45, - 0xaf, 0xe8, 0x3f, 0x62, 0xe8, 0x7e, 0x56, 0x84, 0xc9, 0x60, 0x42, 0xe4, - 0x56, 0x4c, 0xe9, 0x87, 0x6c, 0xb9, 0x4a, 0xfa, 0x71, 0x8f, 0x73, 0x25, - 0x77, 0x1e, 0xb5, 0xea, 0x93, 0xe2, 0x12, 0x3a, 0x7e, 0x2c, 0x42, 0xb0, - 0x38, 0x10, 0x7b, 0x2a, 0xd7, 0xcf, 0x0c, 0xfb, 0x4e, 0x91, 0x6e, 0x86, - 0xad, 0x77, 0xe1, 0xd4, 0x96, 0x74, 0x45, 0x97, 0xa0, 0x9a, 0x14, 0x8c, - 0xa5, 0xd0, 0x7c, 0xde, 0x00, 0xdc, 0x9a, 0xac, 0xba, 0x7e, 0xce, 0x20, - 0xe0, 0xe0, 0x6f, 0x1f, 0x5e, 0xd6, 0x87, 0x5b, 0x56, 0xf0, 0xde, 0xe1, - 0x2a, 0xbd, 0x3e, 0xe5, 0x81, 0x56, 0x37, 0x68, 0x57, 0xdd, 0x5d, 0x31, - 0x58, 0x00, 0x70, 0x58, 0x8c, 0xa0, 0x9f, 0xd5, 0xa1, 0xf7, 0xd9, 0xea, - 0x7d, 0xdd, 0x74, 0x46, 0x2a, 0xdb, 0x30, 0xcb, 0x02, 0x51, 0xd3, 0x4d, - 0xa2, 0xe1, 0x0b, 0x44, 0xbe, 0x8b, 0x44, 0xc3, 0x17, 0x66, 0xa8, 0xe9, - 0x26, 0x51, 0x35, 0x3b, 0x6a, 0x2b, 0xb8, 0xfc, 0xb1, 0x7a, 0xa6, 0x35, - 0x48, 0x98, 0x7d, 0xb5, 0xf2, 0x69, 0xae, 0xa5, 0xa4, 0x89, 0x18, 0xaa, - 0x3e, 0x6f, 0x7b, 0xf4, 0xf5, 0xd2, 0x4c, 0x3b, 0xf8, 0xce, 0x1d, 0x8a, - 0xa7, 0x8b, 0x99, 0xdb, 0xc6, 0xbb, 0xd1, 0xfd, 0xf2, 0xd2, 0x4e, 0x1f, - 0xf1, 0x0b, 0x44, 0x75, 0xdf, 0x02, 0x82, 0xd7, 0x53, 0x70, 0x7c, 0xc7, - 0xa8, 0x79, 0xa8, 0x43, 0x24, 0xa2, 0xec, 0xf3, 0xe0, 0xf5, 0x14, 0x4c, - 0x8f, 0x3e, 0x7c, 0xd7, 0x4e, 0x8f, 0xf1, 0x0b, 0x44, 0xc9, 0xd5, 0xc5, - 0xae, 0x51, 0xe2, 0xda, 0x2c, 0x01, 0x46, 0x48, 0xf1, 0x08, 0x60, 0x6e, - 0x84, 0x2d, 0x93, 0x40, 0xe3, 0x86, 0xa5, 0x9f, 0x13, 0x9e, 0xfc, 0xf4, - 0x2a, 0x85, 0x0c, 0x16, 0xc4, 0xc2, 0x12, 0x06, 0x9d, 0x02, 0x38, 0x43, - 0x0a, 0x75, 0xdf, 0xce, 0xb5, 0x27, 0xf2, 0xc5, 0x0d, 0xf2, 0x4c, 0x9b, - 0x54, 0x25, 0x05, 0xa7, 0x00, 0x91, 0xab, 0xed, 0x9b, 0xbf, 0xf9, 0x9b, - 0xb3, 0x74, 0x3a, 0x63, 0x84, 0x14, 0xc8, 0x3d, 0x31, 0x5a, 0x05, 0x0c, - 0x7d, 0x2f, 0x27, 0x8f, 0xe1, 0xf8, 0x2c, 0x55, 0xf4, 0x25, 0xe7, 0x6a, - 0x5b, 0x6c, 0xd5, 0x92, 0x42, 0x09, 0x60, 0xd3, 0x91, 0xca, 0x3e, 0xf6, - 0xd5, 0xd7, 0x5f, 0x28, 0xd9, 0x21, 0xeb, 0xf6, 0x9d, 0xa2, 0x5a, 0xca, - 0x55, 0x83, 0xd1, 0x0b, 0x44, 0x9e, 0xe9, 0x9c, 0x7e, 0xb4, 0x57, 0x7d, - 0x6c, 0xb2, 0x7d, 0x81, 0x68, 0xcd, 0x1f, 0x8a, 0xf5, 0x1f, 0xdf, 0xee, - 0x46, 0xb2, 0xc4, 0xe2, 0xb1, 0x1a, 0x14, 0x89, 0xc8, 0xf8, 0x96, 0xfc, - 0xf5, 0xb3, 0x2d, 0x63, 0x84, 0xff, 0x65, 0xb5, 0x2f, 0xcd, 0xce, 0x14, - 0x9f, 0x53, 0x9e, 0x72, 0x1a, 0x61, 0x7a, 0x54, 0xff, 0xa9, 0xac, 0x9c, - 0xc1, 0x12, 0xf5, 0x44, 0xd5, 0x72, 0x39, 0xab, 0x80, 0x83, 0xff, 0x92, - 0x23, 0x8c, 0xcc, 0xa7, 0x44, 0x3d, 0xe7, 0xb5, 0xdf, 0x57, 0xaf, 0x29, - 0x86, 0xee, 0xe7, 0xaa, 0x3b, 0xee, 0x29, 0x12, 0x91, 0xfb, 0x64, 0x10, - 0xa7, 0xe7, 0xb5, 0x4f, 0x03, 0xe6, 0xf7, 0xf3, 0xaa, 0x8a, 0xf1, 0xd1, - 0xa4, 0xf4, 0x4f, 0x33, 0x58, 0x00, 0xb0, 0x9b, 0x80, 0x99, 0x5d, 0xee, - 0x8a, 0xf1, 0xda, 0x72, 0x1d, 0x50, 0x6b, 0xb9, 0x6a, 0xd0, 0x33, 0xed, - 0x57, 0xc9, 0x1b, 0xfc, 0x24, 0xa2, 0x7a, 0xde, 0xf9, 0x9f, 0x41, 0xcd, - 0x7a, 0xb7, 0x9e, 0xf0, 0xc3, 0x77, 0x9c, 0x88, 0xaf, 0xd1, 0x45, 0x19, - 0xbe, 0x14, 0x43, 0x3a, 0x23, 0x2c, 0x6e, 0xb0, 0xa4, 0xd4, 0xed, 0x7d, - 0x10, 0x9a, 0xed, 0x95, 0x96, 0xd0, 0x4e, 0x09, 0x40, 0x8a, 0x2f, 0x96, - 0x9b, 0x8e, 0x4a, 0xaa, 0x38, 0x79, 0xd7, 0x0f, 0x00, 0xa7, 0x59, 0xfb, - 0x7d, 0x79, 0xa6, 0x2d, 0x70, 0xff, 0xe9, 0xa3, 0x8a, 0xf1, 0x72, 0x91, - 0x88, 0x2c, 0xef, 0x4e, 0xe0, 0x74, 0xd4, 0xaa, 0x29, 0x67, 0x7c, 0xbb, - 0x9a, 0x18, 0x2a, 0xfa, 0xb4, 0xb3, 0xaf, 0x6a, 0xef, 0x74, 0x2d, 0x25, - 0x45, 0xbe, 0x02, 0xfa, 0xa6, 0x01, 0x7f, 0x89, 0xa8, 0x94, 0x62, 0xb8, - 0x65, 0xf4, 0x2a, 0xd7, 0xe1, 0xb5, 0x96, 0xab, 0x06, 0x8b, 0xe4, 0x99, - 0x1b, 0x0b, 0x5e, 0xb4, 0xa3, 0x64, 0xfd, 0x81, 0xb8, 0x1f, 0xcd, 0x1f, - 0xcb, 0xf7, 0x46, 0xe8, 0xad, 0xd7, 0xc6, 0xab, 0xcf, 0x86, 0xe4, 0x3f, - 0x0f, 0x5e, 0x2f, 0xd6, 0x4b, 0x66, 0xa8, 0xa5, 0x0d, 0x50, 0xc4, 0xb5, - 0xe5, 0x06, 0xaf, 0xe7, 0xf2, 0x25, 0x57, 0x33, 0xd6, 0xf1, 0x12, 0x63, - 0x7f, 0x7b, 0xc5, 0x0d, 0xce, 0x50, 0xdc, 0xee, 0xec, 0x37, 0x7f, 0xae, - 0xdb, 0xda, 0x86, 0xdb, 0x74, 0x53, 0x9e, 0x41, 0xe2, 0x5c, 0x71, 0xbf, - 0x99, 0xb9, 0x20, 0x68, 0x6f, 0xf1, 0x0c, 0xb5, 0xca, 0x9c, 0xd6, 0x66, - 0x06, 0xc4, 0x25, 0xd8, 0xbe, 0x7b, 0x6f, 0x7c, 0xd8, 0xc6, 0x47, 0x00, - 0xcf, 0x87, 0x7e, 0xbc, 0x70, 0x32, 0x05, 0xf6, 0xc7, 0x09, 0x1c, 0x4c, - 0x00, 0x89, 0xaf, 0xe7, 0x55, 0x79, 0xec, 0x26, 0xc0, 0xd5, 0xaa, 0x3d, - 0x82, 0x6d, 0xbc, 0xfb, 0xbe, 0x31, 0x6d, 0x91, 0xbc, 0xb8, 0x9a, 0x69, - 0x11, 0xd3, 0xae, 0x37, 0x8b, 0xe1, 0x69, 0x3f, 0x9a, 0x8f, 0xa5, 0x90, - 0xb8, 0x36, 0xab, 0xcf, 0x70, 0xe3, 0x91, 0x92, 0xed, 0x70, 0x7c, 0xa7, - 0x58, 0x2f, 0xc4, 0x25, 0x08, 0xe6, 0xa5, 0x0d, 0x50, 0xc1, 0xac, 0x2d, - 0xd7, 0xf1, 0x9d, 0xe2, 0xfc, 0xd3, 0xdf, 0x66, 0x2c, 0xf5, 0x1b, 0x37, - 0x6c, 0x99, 0x70, 0x51, 0xfe, 0x74, 0x46, 0x40, 0xc3, 0x21, 0x3f, 0x06, - 0xdf, 0xb9, 0x43, 0xbe, 0x8b, 0x7f, 0xa3, 0xc4, 0x35, 0x79, 0x71, 0x3c, - 0xf8, 0xce, 0x1d, 0x7a, 0xec, 0x7d, 0xbf, 0x32, 0x83, 0xe4, 0x97, 0xeb, - 0x35, 0xc5, 0x10, 0xfb, 0x65, 0x8b, 0xe6, 0x9a, 0x61, 0x95, 0x68, 0x5b, - 0xfc, 0x08, 0xb1, 0x70, 0x44, 0x59, 0x05, 0x84, 0x5a, 0x8b, 0x0d, 0x2e, - 0x96, 0x02, 0x5a, 0xce, 0x00, 0xec, 0x43, 0x80, 0xbd, 0xe5, 0x07, 0xfb, - 0x20, 0x05, 0xf6, 0x41, 0x71, 0xbe, 0x8a, 0x69, 0xb3, 0x4b, 0xae, 0xa7, - 0xde, 0x81, 0x3d, 0x47, 0xe4, 0x7b, 0x0f, 0xd8, 0x07, 0xea, 0x0f, 0x10, - 0x27, 0xbe, 0x0b, 0xe0, 0x71, 0x57, 0x91, 0x7e, 0x16, 0x63, 0x05, 0xc3, - 0xba, 0x8f, 0x4c, 0x2b, 0x58, 0xb4, 0xeb, 0x2d, 0x8c, 0x7e, 0x34, 0x07, - 0x80, 0xe0, 0x65, 0x1d, 0x8c, 0x6b, 0x6e, 0x2c, 0xd9, 0x0e, 0x94, 0x60, - 0xda, 0xc2, 0x01, 0xa5, 0x1b, 0xe3, 0x11, 0xed, 0x76, 0x5c, 0xd7, 0xce, - 0xef, 0x65, 0x8c, 0xf9, 0x5f, 0x7e, 0x86, 0xed, 0x77, 0x1a, 0x35, 0xcb, - 0xc5, 0xd3, 0x93, 0x18, 0x88, 0x99, 0x30, 0x70, 0xcc, 0x0f, 0x4f, 0xc2, - 0x82, 0x78, 0x7a, 0xb2, 0x28, 0x1f, 0x67, 0x15, 0x40, 0x3b, 0x8c, 0xe8, - 0x7e, 0x6e, 0x13, 0x2b, 0xf5, 0xe5, 0xc2, 0x2a, 0x40, 0x3d, 0x82, 0xb3, - 0xe8, 0x7a, 0x20, 0xa6, 0xfa, 0x48, 0xb1, 0x2f, 0x10, 0x01, 0x7b, 0x7b, - 0x1e, 0xeb, 0xde, 0xf3, 0x63, 0xf2, 0xb3, 0x14, 0x30, 0xed, 0x07, 0x16, - 0x47, 0xc8, 0xf8, 0x93, 0x85, 0x16, 0x59, 0x45, 0xba, 0x3e, 0x5d, 0x5c, - 0x6f, 0xdc, 0x0a, 0xf6, 0x96, 0x1f, 0xa9, 0x2c, 0xe9, 0x3e, 0x08, 0xb8, - 0x10, 0x2d, 0xca, 0xd7, 0xfb, 0xa3, 0x0a, 0x86, 0x75, 0x1f, 0x99, 0x56, - 0xaa, 0xc0, 0xb4, 0xf9, 0xd8, 0x79, 0x26, 0x85, 0xc1, 0xb3, 0x33, 0xd5, - 0x19, 0x6e, 0x19, 0xa6, 0x45, 0x09, 0xa6, 0x45, 0xe1, 0x80, 0xd2, 0x89, - 0x30, 0x37, 0x6a, 0xcb, 0xd5, 0x60, 0xda, 0x7c, 0xec, 0x78, 0x8a, 0xb1, - 0x29, 0x27, 0xc0, 0xe9, 0x3c, 0x6b, 0x62, 0xe3, 0xdd, 0xb8, 0xf1, 0x53, - 0x23, 0x62, 0x15, 0x16, 0x8f, 0xab, 0x7a, 0x7f, 0xa4, 0x1e, 0xc1, 0x59, - 0xcc, 0xdf, 0xe9, 0x62, 0x7f, 0x9c, 0x90, 0x77, 0xae, 0xe6, 0x8a, 0x47, - 0x06, 0xcc, 0x02, 0x32, 0x19, 0xe8, 0x4f, 0xa5, 0x18, 0x89, 0x17, 0xf0, - 0xf0, 0x01, 0x3f, 0x42, 0x8b, 0x3b, 0x9c, 0x43, 0x4f, 0xdb, 0x35, 0xf2, - 0x2d, 0x5f, 0xa6, 0x2d, 0x6c, 0x97, 0xad, 0xc9, 0x8d, 0xf1, 0xed, 0x46, - 0xd0, 0x5e, 0x37, 0x8e, 0xbe, 0xfe, 0x30, 0xa3, 0xbd, 0x6e, 0xec, 0x77, - 0x26, 0xc0, 0x59, 0xe5, 0xe7, 0x23, 0x29, 0x0b, 0xfa, 0xfe, 0x63, 0xaa, - 0xe2, 0x62, 0xa5, 0x1c, 0xd3, 0xde, 0x4f, 0x9f, 0xb6, 0x14, 0x9a, 0x1e, - 0x7d, 0x98, 0xa5, 0x76, 0x18, 0x95, 0x76, 0x56, 0x5a, 0x3b, 0x99, 0x6d, - 0x2e, 0x84, 0x76, 0xc8, 0x3e, 0x72, 0x25, 0xbd, 0x56, 0x8d, 0xad, 0x66, - 0x4c, 0xd3, 0xf2, 0x17, 0x13, 0xfb, 0xe3, 0x04, 0x70, 0xcb, 0x51, 0x76, - 0x84, 0xb8, 0x73, 0x5f, 0x78, 0x54, 0x9f, 0x2a, 0x30, 0xd2, 0xa6, 0x23, - 0x7e, 0xd8, 0xc7, 0x80, 0x75, 0x27, 0xd5, 0xff, 0xcf, 0x25, 0xa5, 0x8a, - 0x61, 0x9c, 0xfb, 0xc9, 0xb4, 0x85, 0xed, 0x9a, 0x7a, 0x1a, 0x68, 0xdc, - 0xc0, 0x94, 0xa9, 0xce, 0xcb, 0x18, 0xeb, 0x78, 0xea, 0x31, 0x76, 0xe3, - 0xa7, 0x46, 0xb4, 0x6d, 0x91, 0x7d, 0xf6, 0xd3, 0x51, 0x2b, 0xec, 0x87, - 0xa5, 0xb2, 0xa7, 0xd7, 0x4e, 0x7f, 0x1e, 0x2a, 0xd9, 0x8e, 0xe5, 0xe0, - 0xd3, 0x6a, 0xbe, 0x87, 0x47, 0x74, 0x9c, 0xd3, 0x8e, 0x49, 0xc0, 0xb7, - 0xaa, 0x93, 0xbb, 0x4a, 0x00, 0xd0, 0x66, 0x2d, 0xf6, 0x41, 0x7c, 0x51, - 0x80, 0xbd, 0x3d, 0x01, 0xd4, 0x97, 0x5e, 0x0d, 0x03, 0xd2, 0xa2, 0x6f, - 0x5a, 0x43, 0xaa, 0xc2, 0xf7, 0x0b, 0x7f, 0xe9, 0x07, 0x0c, 0xea, 0xbb, - 0xc3, 0x86, 0xb6, 0x94, 0x5f, 0x84, 0xdd, 0x6f, 0xa6, 0xcd, 0xf7, 0x69, - 0x9d, 0xe6, 0x70, 0x49, 0xe6, 0x48, 0xae, 0x66, 0xcc, 0xf5, 0x43, 0xc6, - 0xc6, 0xb7, 0xcb, 0x51, 0x92, 0xb0, 0xc1, 0x06, 0xf6, 0x86, 0x1f, 0xfc, - 0x17, 0xf2, 0x69, 0xb4, 0x6c, 0x3e, 0x91, 0x88, 0x26, 0x3f, 0x25, 0xf2, - 0x24, 0x4a, 0x47, 0x0f, 0x96, 0x8b, 0x4f, 0x9b, 0x8f, 0xd9, 0xb8, 0x72, - 0x35, 0x3b, 0x9c, 0x80, 0x84, 0x38, 0xe7, 0xa8, 0x38, 0x70, 0x15, 0xa6, - 0x95, 0x00, 0xf8, 0x5f, 0x44, 0x91, 0xe5, 0x77, 0x9e, 0xf4, 0x03, 0x73, - 0xe5, 0x19, 0x16, 0x10, 0x80, 0xaf, 0xd4, 0xdf, 0xff, 0x54, 0x9d, 0x74, - 0xf8, 0x7e, 0xf9, 0x68, 0xe1, 0x52, 0x95, 0x0d, 0xab, 0x4c, 0x79, 0xc3, - 0xed, 0x3b, 0x4b, 0xda, 0xca, 0xd5, 0xeb, 0xd3, 0x56, 0x92, 0x97, 0xdc, - 0xc0, 0xd8, 0x8d, 0x5f, 0xbb, 0xc1, 0x25, 0xe5, 0xff, 0xd9, 0x7a, 0xc2, - 0x0f, 0x76, 0x28, 0x85, 0x75, 0xfb, 0x4e, 0xd1, 0xce, 0x7d, 0xb3, 0xc4, - 0xde, 0xf0, 0xa3, 0xe7, 0x7c, 0xf1, 0x79, 0x67, 0x55, 0x7b, 0xef, 0x91, - 0x4f, 0x9b, 0xe6, 0xf5, 0xfb, 0xb4, 0x7c, 0xde, 0x65, 0x85, 0x5a, 0x51, - 0x81, 0x72, 0x18, 0x4e, 0xca, 0xe1, 0xb1, 0xa6, 0x9b, 0xe5, 0x0d, 0x77, - 0x95, 0x00, 0x79, 0xca, 0x32, 0xdb, 0x8a, 0x57, 0xe9, 0xd5, 0xe0, 0xe8, - 0x66, 0x47, 0x69, 0xc3, 0x2c, 0x97, 0xaa, 0x60, 0xda, 0x42, 0x74, 0x9a, - 0x8d, 0x55, 0x6d, 0x89, 0x96, 0x93, 0x93, 0xca, 0xd4, 0xdd, 0x53, 0xa6, - 0x55, 0xb7, 0xab, 0x3a, 0xb9, 0x93, 0x0f, 0xc9, 0xe1, 0x22, 0xad, 0x38, - 0x67, 0x35, 0x33, 0x46, 0xe4, 0xab, 0x62, 0xbd, 0x60, 0x16, 0x20, 0x05, - 0x6a, 0x6f, 0xa7, 0x00, 0xc0, 0x7f, 0x7e, 0x42, 0x53, 0x6e, 0xa9, 0x55, - 0xbd, 0xe5, 0x1a, 0x51, 0xe3, 0x7f, 0xcd, 0x63, 0xeb, 0x09, 0x6d, 0x86, - 0xb5, 0xf1, 0x46, 0x4c, 0xed, 0x90, 0x7d, 0xfa, 0xf1, 0xed, 0x6e, 0x98, - 0xb9, 0x60, 0x51, 0xbe, 0x34, 0x2f, 0xe0, 0xb1, 0xf7, 0xfd, 0x48, 0x5c, - 0x54, 0xcf, 0x38, 0x45, 0x4c, 0x2b, 0x00, 0x18, 0x34, 0x27, 0x51, 0x0b, - 0xf3, 0x8d, 0x7d, 0x1e, 0x2a, 0x69, 0x97, 0x65, 0x53, 0xc1, 0xce, 0x52, - 0x35, 0x28, 0xfd, 0xbc, 0x4a, 0xc3, 0x2a, 0x23, 0xe7, 0xb1, 0xf7, 0xfd, - 0x08, 0x5e, 0x26, 0x4a, 0x5c, 0x9b, 0xad, 0xbc, 0xf8, 0xd1, 0x40, 0x7d, - 0x3e, 0x6d, 0xf5, 0x72, 0xbd, 0xac, 0x74, 0x9c, 0x53, 0x0b, 0xf3, 0xcb, - 0xd7, 0x7d, 0x9b, 0x31, 0xad, 0x78, 0x7b, 0x20, 0x9e, 0xaa, 0xf9, 0xfa, - 0xd4, 0xc1, 0xb3, 0x33, 0x14, 0x4f, 0x17, 0xcf, 0xb4, 0x5d, 0xc6, 0xe2, - 0x6f, 0xf4, 0x44, 0x92, 0xe3, 0xae, 0xec, 0x58, 0x0a, 0xf1, 0xf0, 0x64, - 0x91, 0x1e, 0x36, 0xde, 0x8d, 0x29, 0x27, 0xe0, 0x7f, 0x99, 0xb1, 0xe8, - 0xa3, 0xb2, 0x4f, 0x9f, 0xdc, 0xc0, 0x98, 0xf4, 0xab, 0xad, 0x6c, 0xc8, - 0x9a, 0xd6, 0x8c, 0x32, 0x0c, 0x04, 0xfc, 0x30, 0xbe, 0x9f, 0xc2, 0xe4, - 0xa7, 0x57, 0x8b, 0xf4, 0x57, 0xee, 0x3d, 0x70, 0x6c, 0x5c, 0xc7, 0x9c, - 0xe6, 0xb0, 0x6e, 0xa6, 0x9d, 0xac, 0xaf, 0xe1, 0x3c, 0x6d, 0x0c, 0xba, - 0xeb, 0x71, 0x3a, 0xab, 0xbf, 0x1a, 0xa9, 0x92, 0xbc, 0x91, 0x33, 0x7e, - 0x34, 0x07, 0x00, 0xf6, 0x86, 0x1f, 0x3b, 0x8f, 0xcf, 0xd2, 0xba, 0x7d, - 0xa7, 0xa8, 0x14, 0x26, 0x2e, 0x12, 0x45, 0xf2, 0xbe, 0x2c, 0xd0, 0x1b, - 0xa7, 0xd5, 0x63, 0x28, 0xd9, 0x38, 0x67, 0x97, 0x4d, 0x3b, 0xce, 0x59, - 0x4e, 0x6e, 0xec, 0x97, 0x2d, 0x9a, 0x4c, 0x3d, 0x10, 0x33, 0x41, 0x3c, - 0x4e, 0xe4, 0xba, 0x5d, 0xf9, 0x94, 0x9b, 0x65, 0x41, 0xce, 0x27, 0xbc, - 0x33, 0x4e, 0x23, 0xa9, 0xe2, 0xaf, 0xb3, 0x6d, 0x7c, 0x18, 0xde, 0x56, - 0x7b, 0x91, 0xc1, 0x5a, 0xde, 0x9d, 0x40, 0xa1, 0xcf, 0x9d, 0xc5, 0xf1, - 0xed, 0xf2, 0x21, 0xa5, 0x52, 0x33, 0xa4, 0xeb, 0x87, 0xeb, 0x58, 0xea, - 0x15, 0x23, 0x6c, 0x4d, 0xc5, 0x3b, 0xa0, 0xe9, 0x8c, 0x84, 0x9e, 0x28, - 0x07, 0xf1, 0x38, 0xa9, 0x08, 0x46, 0x75, 0xc3, 0x8c, 0x48, 0xb2, 0x2f, - 0xa2, 0x77, 0x32, 0xa1, 0xbd, 0xfa, 0xb6, 0x7a, 0xf5, 0xde, 0x87, 0xc0, - 0x19, 0x04, 0x44, 0x5e, 0x31, 0x54, 0x7d, 0x6a, 0x68, 0xe7, 0xbe, 0x59, - 0xaa, 0x7d, 0x52, 0xd4, 0xc6, 0xec, 0xa9, 0xb2, 0x75, 0x05, 0xa7, 0xe2, - 0xf6, 0x3b, 0x13, 0xe8, 0x78, 0xea, 0x31, 0x45, 0xaf, 0xfc, 0xfb, 0x23, - 0x9c, 0x66, 0x37, 0x3a, 0x5e, 0xaa, 0xed, 0x90, 0x4c, 0xf0, 0xf2, 0x55, - 0xea, 0x3c, 0xc3, 0x55, 0xd4, 0x47, 0xcb, 0x80, 0xe2, 0x69, 0x47, 0xc9, - 0x72, 0x4e, 0x73, 0x18, 0x46, 0xab, 0x00, 0x5b, 0x26, 0xb2, 0x18, 0x87, - 0x8d, 0x40, 0x8a, 0x35, 0x22, 0x9d, 0x29, 0xff, 0x9b, 0x19, 0x4e, 0x73, - 0x18, 0xd2, 0xcf, 0x73, 0xae, 0x01, 0xbf, 0x40, 0x34, 0x10, 0x07, 0x3c, - 0x27, 0xb4, 0xdf, 0x23, 0x67, 0x90, 0x10, 0x79, 0xc5, 0x8d, 0xc9, 0x87, - 0x74, 0xdc, 0xc1, 0x76, 0x99, 0x68, 0xe4, 0x4c, 0x65, 0x79, 0xaa, 0xfb, - 0x69, 0xbd, 0x4c, 0xde, 0x43, 0xd6, 0xc3, 0x80, 0x30, 0x0b, 0xe8, 0x0b, - 0x44, 0xb4, 0x6c, 0xb3, 0x64, 0x1a, 0x29, 0xe1, 0x2b, 0x95, 0xc2, 0xa1, - 0x2d, 0x46, 0x5d, 0xc7, 0xdc, 0x7a, 0x9b, 0x62, 0xba, 0x99, 0xbc, 0x1c, - 0xee, 0x77, 0x26, 0x14, 0xf9, 0x4e, 0xa7, 0xba, 0x7f, 0xfa, 0x9f, 0x54, - 0x33, 0xed, 0xd0, 0x4f, 0x72, 0x71, 0x65, 0xbb, 0xa9, 0xf6, 0x61, 0xe2, - 0xd8, 0xb8, 0x8e, 0xd1, 0x0e, 0x6d, 0x06, 0xb2, 0xf1, 0xe1, 0x92, 0x4c, - 0x2d, 0xfd, 0x6a, 0x2b, 0x1b, 0xdd, 0x66, 0x44, 0xaf, 0x46, 0x39, 0x40, - 0x42, 0x00, 0x36, 0x9c, 0x3e, 0xef, 0x57, 0x76, 0xa6, 0x06, 0x62, 0x26, - 0x04, 0xe2, 0x7e, 0x84, 0x0d, 0xda, 0x37, 0xbc, 0x0f, 0x6d, 0x71, 0x63, - 0x6a, 0x87, 0x11, 0xde, 0x97, 0x9e, 0x51, 0xed, 0x50, 0x8d, 0xfc, 0x65, - 0xd1, 0x60, 0x35, 0xfa, 0xcb, 0x69, 0x0e, 0x23, 0xf5, 0x1b, 0x7d, 0x06, - 0x2b, 0x00, 0x70, 0x6c, 0x64, 0xec, 0xce, 0xbf, 0x69, 0xfb, 0xf6, 0x69, - 0x5e, 0xde, 0x0a, 0x76, 0xdd, 0x26, 0xd2, 0xbc, 0x9f, 0xb6, 0x9c, 0xc5, - 0x6b, 0xa2, 0x41, 0xc0, 0xd4, 0x8b, 0xf2, 0x81, 0xee, 0x4a, 0x49, 0xef, - 0xdd, 0x5e, 0x5d, 0xb6, 0x18, 0xfa, 0x9f, 0xd7, 0x7f, 0x9b, 0x61, 0xe1, - 0xb9, 0xd7, 0x5a, 0xb1, 0xd2, 0x79, 0xd9, 0x52, 0xcf, 0x13, 0x5f, 0xdf, - 0xbd, 0xdf, 0x90, 0xa8, 0xf5, 0x7c, 0xae, 0x48, 0x44, 0xbe, 0xcf, 0x62, - 0x88, 0x71, 0x16, 0xe5, 0x7c, 0x6a, 0x2c, 0xad, 0xcd, 0xc4, 0x36, 0x3e, - 0x0c, 0xce, 0x20, 0xc0, 0x58, 0x17, 0x84, 0xed, 0x47, 0x0e, 0xd8, 0x32, - 0x09, 0xb4, 0xac, 0x37, 0x95, 0x74, 0xc9, 0x82, 0x97, 0xaf, 0x92, 0x37, - 0x6c, 0x41, 0x38, 0x29, 0x47, 0x09, 0xb2, 0x0c, 0xde, 0xc5, 0x2d, 0xfd, - 0x1c, 0xaf, 0x48, 0x44, 0xc3, 0x97, 0x62, 0xf0, 0x47, 0x65, 0x3b, 0x09, - 0xc4, 0x6d, 0x30, 0x73, 0x41, 0x58, 0xb8, 0x16, 0xf8, 0xb6, 0xcd, 0x97, - 0xb8, 0x9f, 0x76, 0x81, 0xc8, 0xfe, 0x31, 0x10, 0x9e, 0xd6, 0xf1, 0xed, - 0xd8, 0x66, 0x17, 0xa6, 0xbe, 0x57, 0x07, 0x47, 0xde, 0x25, 0x13, 0x85, - 0xe9, 0xe0, 0x34, 0xb0, 0xe7, 0x4a, 0xf5, 0xf7, 0xd3, 0xea, 0xb9, 0x2d, - 0x71, 0x05, 0xbf, 0x39, 0x58, 0xf2, 0x26, 0x70, 0x7e, 0x81, 0xa8, 0xf9, - 0x18, 0x74, 0xff, 0xd6, 0x82, 0xeb, 0x71, 0xed, 0x8f, 0x1d, 0xed, 0x63, - 0x41, 0x84, 0xbf, 0xb4, 0x56, 0x2d, 0xa7, 0xcd, 0x1a, 0x85, 0xff, 0x45, - 0xc7, 0xb2, 0xbf, 0xe8, 0x78, 0x05, 0xff, 0xf9, 0x58, 0xf1, 0x77, 0xc4, - 0x0c, 0x97, 0x89, 0x3a, 0xcf, 0xd4, 0xf6, 0xb5, 0x6e, 0xad, 0xd8, 0x65, - 0xac, 0xcd, 0x25, 0x58, 0xc1, 0x6f, 0x06, 0x56, 0xf5, 0x3b, 0x62, 0x4d, - 0x37, 0xe5, 0x6b, 0x40, 0xd3, 0x99, 0x7b, 0xab, 0x12, 0x67, 0x10, 0x30, - 0xb4, 0xa5, 0xba, 0x7b, 0x68, 0x57, 0xf0, 0x9b, 0x8b, 0x55, 0xfd, 0x8e, - 0x58, 0xf6, 0x80, 0x6f, 0x2d, 0x71, 0x5c, 0x3d, 0x71, 0xd8, 0xd4, 0x2b, - 0xc6, 0x15, 0x83, 0x5d, 0xc1, 0x8a, 0xa8, 0xfb, 0xb7, 0x71, 0x13, 0xd7, - 0x66, 0xa9, 0x3f, 0x60, 0x44, 0x20, 0x7e, 0x77, 0xee, 0x9d, 0x2d, 0x8c, - 0xff, 0xdd, 0xef, 0x0e, 0x59, 0xc1, 0xe5, 0x8f, 0x35, 0xfd, 0x36, 0xae, - 0x04, 0x39, 0x2c, 0xd1, 0xf7, 0x21, 0xe0, 0xcf, 0xcc, 0xcb, 0x5b, 0x77, - 0x66, 0xa1, 0x6a, 0x9f, 0xd5, 0x9c, 0x0e, 0x62, 0x68, 0x4b, 0x0b, 0x5a, - 0x78, 0xa8, 0x6e, 0x68, 0x59, 0xc1, 0x15, 0xac, 0x06, 0x97, 0xf4, 0x2b, - 0xe4, 0xf9, 0x06, 0xec, 0xfb, 0x2c, 0x06, 0x0b, 0x67, 0x81, 0xe7, 0x7f, - 0x82, 0x48, 0xcd, 0xab, 0xe3, 0x80, 0xd9, 0x1d, 0x18, 0xf1, 0x07, 0x8d, - 0x00, 0x56, 0x7e, 0x03, 0x77, 0x05, 0x97, 0x86, 0xff, 0x07, 0xeb, 0x01, - 0x34, 0x67, 0x1a, 0xc4, 0xce, 0x23, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, - 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x08, 0x06, 0x00, 0x00, 0x00, 0x63, 0x57, 0xfa, 0xde, 0x00, 0x00, 0x13, + 0x1e, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0xed, 0x5d, 0x7f, 0x68, 0x1b, + 0x57, 0x9e, 0xff, 0x3c, 0x73, 0x5b, 0xe4, 0xe0, 0x2d, 0x52, 0xd9, 0x16, + 0x29, 0xd0, 0x62, 0x97, 0x26, 0x58, 0xde, 0x63, 0x41, 0xda, 0x18, 0x1a, + 0x85, 0x0d, 0x91, 0x7a, 0x85, 0xad, 0x1c, 0x17, 0x3a, 0xba, 0x5d, 0x88, + 0xed, 0xdd, 0x52, 0x29, 0x49, 0xc9, 0x3a, 0x77, 0x4b, 0x6b, 0xa7, 0x70, + 0xe4, 0x47, 0x71, 0xec, 0x72, 0x24, 0x8e, 0x12, 0x72, 0x67, 0xef, 0xe2, + 0x24, 0x72, 0x30, 0xb5, 0x65, 0xc8, 0x46, 0x2a, 0x38, 0xb6, 0x73, 0x64, + 0xb1, 0x54, 0x7c, 0xc8, 0x5e, 0x92, 0x5a, 0x2a, 0x59, 0x2c, 0x19, 0xa7, + 0xd8, 0xc1, 0x59, 0x6c, 0xe3, 0x2e, 0xb6, 0xd0, 0x1a, 0xd7, 0x98, 0x83, + 0xef, 0xfd, 0x31, 0xd6, 0x48, 0x23, 0xcd, 0x48, 0x33, 0x92, 0xb3, 0x4d, + 0xb7, 0x7a, 0x60, 0x3e, 0x4d, 0xe7, 0xbd, 0xef, 0xfb, 0x7e, 0xdf, 0x7c, + 0xdf, 0xe7, 0x7d, 0xdf, 0x77, 0xde, 0x8c, 0xb0, 0x0a, 0xe0, 0x06, 0x80, + 0x9d, 0x42, 0x22, 0x22, 0x5a, 0x20, 0x22, 0x22, 0x0a, 0x6d, 0x23, 0x6d, + 0x11, 0xed, 0x74, 0x3f, 0x25, 0xfc, 0xfe, 0x62, 0xd1, 0x0e, 0x3a, 0x3c, + 0xbb, 0x48, 0xa1, 0x05, 0x22, 0x53, 0xcf, 0x18, 0xa1, 0x8d, 0x08, 0x6d, + 0xb7, 0x65, 0xd1, 0xda, 0x47, 0xd4, 0x72, 0x6f, 0x8a, 0x88, 0x88, 0xbe, + 0x6d, 0xc3, 0x4b, 0xf8, 0xdd, 0xc5, 0x82, 0x1a, 0x4e, 0xaf, 0x10, 0x0d, + 0xcf, 0x12, 0x69, 0x2f, 0xdc, 0x26, 0xdc, 0xda, 0x76, 0x4c, 0x95, 0xa8, + 0x1d, 0x22, 0x72, 0x0e, 0x51, 0xc9, 0x81, 0x4b, 0xa8, 0x1a, 0x55, 0x35, + 0x20, 0x22, 0xb2, 0xf6, 0xe5, 0x67, 0x54, 0xb5, 0x68, 0xed, 0x23, 0x5a, + 0x4c, 0x6c, 0x94, 0x42, 0x88, 0x12, 0x2a, 0x42, 0x45, 0x15, 0x69, 0x8b, + 0x8f, 0x4f, 0x0b, 0x61, 0x54, 0x35, 0xd8, 0x3e, 0x3e, 0x5d, 0x72, 0xdc, + 0x12, 0xe6, 0xc5, 0xbc, 0x15, 0xa6, 0x57, 0x56, 0xc9, 0xd4, 0xb3, 0xb3, + 0xcc, 0x9a, 0x0b, 0x4d, 0x3d, 0x63, 0xa5, 0x90, 0xa1, 0x84, 0x39, 0x31, + 0x67, 0x05, 0x5a, 0x21, 0xd2, 0x0e, 0x3d, 0x7d, 0x86, 0xcd, 0x44, 0xed, + 0x85, 0xdb, 0x25, 0xc7, 0x2d, 0xa1, 0x2c, 0xca, 0x5e, 0x98, 0x5e, 0x59, + 0x25, 0xed, 0x85, 0x02, 0x18, 0xb3, 0x7b, 0x98, 0xd0, 0x43, 0x84, 0x9e, + 0x31, 0x42, 0x0f, 0x91, 0xdd, 0xcf, 0x67, 0x0b, 0x6e, 0x47, 0x17, 0x29, + 0xb4, 0xa8, 0x5c, 0xce, 0x4e, 0x38, 0x2e, 0x11, 0x51, 0x57, 0xcf, 0x0d, + 0x72, 0x1e, 0x73, 0x66, 0xfd, 0x75, 0xba, 0x3b, 0x89, 0x66, 0x89, 0x16, + 0x17, 0x17, 0xbf, 0x33, 0x21, 0x09, 0x11, 0xd1, 0xf0, 0xd0, 0x30, 0xd1, + 0xc6, 0xce, 0x4d, 0xe8, 0x8d, 0xc4, 0x06, 0x75, 0xba, 0x3b, 0xc9, 0x79, + 0xcc, 0x49, 0xfb, 0x0f, 0x59, 0xc9, 0x79, 0xcc, 0x49, 0x34, 0x5b, 0x98, + 0xfc, 0xa7, 0xa1, 0x9f, 0x14, 0xee, 0x0c, 0xc3, 0x5e, 0xb8, 0x4d, 0x73, + 0xab, 0x44, 0x94, 0xa0, 0x9c, 0x25, 0x34, 0x47, 0x7f, 0x17, 0xc6, 0xa5, + 0x04, 0xd1, 0xd4, 0xad, 0x69, 0x32, 0xee, 0x33, 0xd1, 0xe9, 0x7d, 0xed, + 0x64, 0xdc, 0x67, 0x12, 0xfe, 0xa4, 0xfe, 0x7d, 0xba, 0xad, 0xfd, 0x3b, + 0xc1, 0xec, 0xa7, 0xdb, 0xda, 0x05, 0xfd, 0x77, 0xca, 0x31, 0x86, 0xdd, + 0xc3, 0x59, 0xe3, 0xf1, 0x9b, 0x53, 0x2d, 0x05, 0x4d, 0xe4, 0xa7, 0xa1, + 0x9f, 0x22, 0xa6, 0xdd, 0xd8, 0x22, 0xd5, 0x0c, 0xab, 0xa4, 0x38, 0x47, + 0xa7, 0x0a, 0x8a, 0x71, 0x0b, 0x71, 0x5c, 0xe7, 0x31, 0xa7, 0xe8, 0x46, + 0x58, 0x0f, 0xdb, 0xa9, 0xab, 0xe7, 0x06, 0xd1, 0x0a, 0x51, 0xff, 0x40, + 0x3f, 0xcd, 0xb9, 0xe7, 0xc8, 0x7a, 0xd8, 0x2e, 0xaa, 0x33, 0x15, 0x9e, + 0x7a, 0xe6, 0x19, 0x97, 0x88, 0xd7, 0x9f, 0x56, 0x76, 0xc6, 0x21, 0x68, + 0x85, 0x44, 0x63, 0x60, 0xdc, 0x67, 0xe2, 0x99, 0xb6, 0xc0, 0x09, 0xbc, + 0xd3, 0xfa, 0x29, 0x66, 0x5a, 0xeb, 0x7d, 0x95, 0x31, 0x68, 0x20, 0xbf, + 0xc3, 0x9a, 0x06, 0x42, 0x45, 0xc5, 0xb8, 0xd6, 0xbe, 0x31, 0xc5, 0x0e, + 0x45, 0x44, 0x22, 0x46, 0x1d, 0xf3, 0x84, 0x64, 0x07, 0x90, 0x66, 0x89, + 0x36, 0xc2, 0x1b, 0x34, 0x3c, 0x34, 0x9c, 0x53, 0x3e, 0xcd, 0xd2, 0x8e, + 0x84, 0x2a, 0x39, 0xaf, 0x17, 0xc1, 0x4c, 0xb4, 0x48, 0xaa, 0x99, 0x8d, + 0x88, 0x68, 0xff, 0x21, 0x6b, 0xd6, 0x0a, 0x34, 0x37, 0x3a, 0x97, 0x73, + 0xbc, 0xfe, 0x1e, 0xfa, 0xd1, 0x62, 0xee, 0xf1, 0x66, 0x37, 0x00, 0x70, + 0x00, 0xfc, 0x00, 0xec, 0x09, 0xa2, 0xdd, 0x57, 0x7c, 0x00, 0x1c, 0x00, + 0x94, 0xa1, 0xb3, 0x36, 0x0c, 0xcf, 0x5b, 0x66, 0xc8, 0x15, 0xd7, 0xdd, + 0x30, 0x7a, 0x1f, 0x98, 0x15, 0xcb, 0x93, 0xc3, 0xfe, 0x77, 0xe6, 0x61, + 0xff, 0xc9, 0xab, 0xcc, 0x9f, 0xa6, 0xaf, 0x14, 0xce, 0x87, 0xa7, 0xa8, + 0xe9, 0xf8, 0x51, 0xa1, 0x7f, 0xab, 0xd5, 0x86, 0x8e, 0x4e, 0x77, 0xde, + 0x76, 0xe9, 0xe8, 0x5a, 0x21, 0x72, 0xfc, 0xb6, 0x11, 0xb1, 0x47, 0x31, + 0x49, 0x9b, 0xac, 0x56, 0x1b, 0x5a, 0x8f, 0x35, 0x43, 0xbb, 0xf7, 0x55, + 0x56, 0x77, 0xc8, 0x4a, 0xf1, 0xf5, 0x38, 0xb4, 0x15, 0x5a, 0x4c, 0xdc, + 0x0a, 0xc0, 0xf3, 0x12, 0x63, 0xe9, 0xf2, 0x22, 0xe3, 0x21, 0x3a, 0x73, + 0xee, 0x0c, 0xe2, 0xeb, 0x71, 0x18, 0xf7, 0x18, 0x61, 0x1f, 0xf4, 0xb2, + 0xa4, 0x9e, 0x9e, 0xc1, 0x4d, 0x44, 0x1e, 0xf0, 0xd7, 0xd2, 0x8b, 0x71, + 0x8f, 0x11, 0xfb, 0xf7, 0x99, 0xd0, 0xfa, 0x61, 0x2b, 0x3c, 0x2c, 0x25, + 0xcf, 0xe6, 0x9e, 0xa3, 0xba, 0x41, 0x07, 0x00, 0xa0, 0xeb, 0x72, 0x17, + 0x4c, 0x07, 0x0f, 0x30, 0x6f, 0xcf, 0x0d, 0xea, 0xbe, 0xde, 0x2d, 0xb4, + 0xd5, 0xeb, 0x0d, 0x58, 0x5e, 0x5e, 0x02, 0x00, 0x4c, 0x7d, 0x10, 0x82, + 0xb7, 0x71, 0x17, 0x93, 0xb2, 0x33, 0xa9, 0xb7, 0x54, 0x89, 0x7a, 0xc3, + 0xf0, 0xec, 0x65, 0xcc, 0x35, 0x4b, 0x64, 0xfb, 0xb0, 0x4e, 0x90, 0x97, + 0x5e, 0xb4, 0x15, 0x5a, 0x74, 0x59, 0xbb, 0x60, 0x38, 0xa6, 0x83, 0x66, + 0xf7, 0x6e, 0xa6, 0x54, 0x3f, 0x6d, 0x85, 0x56, 0xb0, 0x37, 0xa9, 0x9f, + 0x8b, 0x88, 0xba, 0xaf, 0x79, 0xe0, 0xbb, 0xe3, 0xcf, 0xea, 0x4b, 0xaf, + 0x37, 0x60, 0xa0, 0xbe, 0x1f, 0xda, 0x23, 0x1a, 0x6c, 0x3e, 0xbf, 0x8b, + 0xf9, 0x01, 0x94, 0x09, 0x37, 0x8a, 0x88, 0x6a, 0x7e, 0xef, 0x03, 0x8c, + 0xdb, 0x8e, 0xa2, 0x10, 0xb9, 0x6a, 0x79, 0x87, 0x9d, 0x98, 0x07, 0x7a, + 0xd7, 0xcd, 0xaa, 0xe4, 0xc9, 0xe1, 0xc9, 0xc7, 0x55, 0xd0, 0x6d, 0x11, + 0xe5, 0x73, 0x38, 0xb3, 0x49, 0xac, 0x8f, 0x2e, 0xa8, 0x85, 0xe3, 0xb0, + 0x9d, 0x6c, 0xa3, 0x73, 0x14, 0x19, 0x0f, 0x91, 0x6b, 0x83, 0x28, 0x9f, + 0xe3, 0xd6, 0xd8, 0xcd, 0x88, 0x3d, 0x8a, 0x41, 0x5b, 0xa1, 0x45, 0xd4, + 0x1b, 0xe6, 0xff, 0xc6, 0xc3, 0xb0, 0x5a, 0x6d, 0xe0, 0xc0, 0x21, 0x18, + 0x0c, 0xa0, 0xf1, 0xb8, 0x0b, 0xba, 0x04, 0x11, 0x07, 0xfe, 0x26, 0xc5, + 0xd7, 0xe3, 0xb0, 0x39, 0xeb, 0xb2, 0xe4, 0xc5, 0x2e, 0xc6, 0x84, 0x9b, + 0xb4, 0xf6, 0xb7, 0x38, 0x38, 0x00, 0x1e, 0x77, 0x27, 0x35, 0x1d, 0x3f, + 0x8a, 0x60, 0xf0, 0x24, 0x6c, 0xeb, 0x36, 0xe8, 0xf5, 0x06, 0x74, 0x1e, + 0x69, 0xc7, 0x7e, 0x93, 0x09, 0xce, 0x0a, 0x17, 0x62, 0x8f, 0x62, 0xe8, + 0x1d, 0xf4, 0xa2, 0xa6, 0xd6, 0x0c, 0xd7, 0x6c, 0x4a, 0xdf, 0xba, 0x41, + 0x07, 0x38, 0x70, 0x00, 0x00, 0x23, 0x8c, 0xf0, 0x03, 0xa8, 0x5c, 0xd7, + 0x8b, 0xec, 0xb5, 0x2c, 0xef, 0x17, 0xfe, 0xfb, 0x93, 0xaf, 0xdc, 0xb2, + 0x76, 0x8e, 0x5d, 0x1e, 0x01, 0x00, 0x41, 0x5e, 0xb2, 0x74, 0x9d, 0xe8, + 0x02, 0xf4, 0xdb, 0xe3, 0xd0, 0x60, 0x86, 0x65, 0x79, 0x3f, 0xf4, 0x7a, + 0x03, 0xa2, 0xde, 0x30, 0xfa, 0xaf, 0xdd, 0x10, 0xc6, 0x21, 0xbe, 0x1e, + 0x47, 0xd3, 0x9d, 0x26, 0xf8, 0x8f, 0x8f, 0x42, 0x8d, 0x7e, 0xb6, 0x75, + 0x9b, 0x48, 0x3f, 0x17, 0x11, 0x59, 0xac, 0x36, 0x74, 0x5f, 0xef, 0xc6, + 0xf2, 0xf2, 0x12, 0x9a, 0xf5, 0xcd, 0xe0, 0xea, 0x39, 0x8c, 0x9c, 0xf7, + 0xc1, 0xb8, 0xc7, 0x08, 0xcb, 0xf2, 0x7e, 0xbc, 0x71, 0xfd, 0x0d, 0xbc, + 0xf1, 0x76, 0x1d, 0x74, 0xb3, 0xfc, 0xfd, 0x17, 0x98, 0xb6, 0x75, 0x68, + 0x8a, 0x7a, 0x23, 0x05, 0x30, 0xa2, 0x3e, 0x00, 0x3a, 0x6e, 0x83, 0x54, + 0x71, 0xcd, 0x03, 0xbd, 0x9f, 0x16, 0xc7, 0xb0, 0xe9, 0xd8, 0x7e, 0xc2, + 0x01, 0x43, 0x06, 0x93, 0x49, 0x32, 0xe5, 0x2c, 0x51, 0x4d, 0x83, 0xfc, + 0x64, 0x02, 0xf8, 0x19, 0x6f, 0xdc, 0x53, 0x05, 0xdb, 0x21, 0x1b, 0x1a, + 0x1b, 0x1a, 0x45, 0x8c, 0xe6, 0x22, 0xa2, 0x70, 0x24, 0x8c, 0x2a, 0xf3, + 0x4f, 0xb3, 0x18, 0xfa, 0xc0, 0x3e, 0x13, 0x25, 0x65, 0x44, 0xc7, 0xc3, + 0xe8, 0xfe, 0xd4, 0x83, 0x74, 0x26, 0x19, 0x1b, 0x1a, 0x11, 0x98, 0xc7, + 0x45, 0x44, 0x35, 0xb5, 0x29, 0x3d, 0xa2, 0xde, 0x30, 0x46, 0x66, 0x46, + 0x70, 0xea, 0xfc, 0x59, 0x41, 0x87, 0xe6, 0x63, 0x2e, 0xd8, 0x1b, 0x9b, + 0x44, 0xfd, 0x34, 0x0c, 0x6c, 0xd0, 0x4f, 0xaf, 0x1c, 0x48, 0xb5, 0x1b, + 0x0d, 0xc3, 0xf3, 0x12, 0x63, 0xee, 0xb4, 0xbe, 0x9b, 0x8f, 0x35, 0xa3, + 0xe1, 0xfd, 0xa3, 0xac, 0xf5, 0x98, 0x93, 0x26, 0x23, 0x11, 0x91, 0x6d, + 0xc6, 0x3d, 0x46, 0x38, 0x8f, 0x34, 0xc0, 0xf2, 0xf6, 0x61, 0x36, 0x3a, + 0xd0, 0x4f, 0x13, 0x5f, 0x56, 0x61, 0x33, 0xee, 0x01, 0x00, 0x98, 0xf7, + 0x59, 0xd0, 0x7c, 0xdc, 0x05, 0x0f, 0x63, 0x2c, 0xb3, 0x1f, 0xae, 0x9e, + 0x43, 0xd5, 0xc7, 0x67, 0xf3, 0x8e, 0x43, 0x96, 0x5d, 0xe3, 0x61, 0x78, + 0x76, 0xa9, 0xd7, 0xaf, 0xae, 0xbe, 0x0e, 0xae, 0xe3, 0x2e, 0x24, 0xaf, + 0x5b, 0xad, 0x36, 0x98, 0x3b, 0xdd, 0xa2, 0xfb, 0xeb, 0x6e, 0x6b, 0x27, + 0xff, 0x1d, 0x3f, 0x00, 0x60, 0xbf, 0xc9, 0x04, 0xcb, 0xf5, 0x5e, 0x56, + 0xc6, 0x01, 0xd0, 0x6d, 0x11, 0xf9, 0x51, 0x20, 0x23, 0xea, 0x6c, 0x88, + 0x7e, 0x9d, 0xe5, 0x13, 0x00, 0x00, 0x4f, 0x05, 0x8a, 0x66, 0xd8, 0x74, + 0x74, 0xdf, 0xf4, 0xc1, 0x45, 0xf9, 0x99, 0xd2, 0xb3, 0x97, 0xb1, 0xe8, + 0x83, 0x30, 0x9c, 0x47, 0x1a, 0x70, 0xba, 0xfe, 0x34, 0x7f, 0x43, 0x32, + 0x18, 0xc5, 0xb6, 0x6e, 0xc3, 0x64, 0x24, 0x82, 0x4f, 0xae, 0xb8, 0x51, + 0x53, 0x6b, 0x86, 0x7d, 0x7c, 0x55, 0x90, 0xeb, 0x61, 0x8c, 0xa5, 0xdf, + 0xa8, 0xf9, 0xf0, 0x14, 0x35, 0x84, 0x37, 0xc8, 0x71, 0xd8, 0x2e, 0xdc, + 0x14, 0x0e, 0x1c, 0x30, 0x03, 0x34, 0x1f, 0x77, 0x41, 0x5b, 0xa1, 0x4d, + 0xc9, 0xff, 0x4a, 0x23, 0xe8, 0x71, 0xe6, 0x7c, 0x87, 0xd0, 0x5f, 0xb3, + 0xbe, 0x19, 0x9e, 0xbd, 0x8c, 0xb9, 0xaf, 0x2d, 0x0b, 0xed, 0xa5, 0x1c, + 0x96, 0x03, 0xe0, 0x6d, 0xdc, 0xc5, 0xfa, 0x3f, 0xea, 0x4f, 0xb5, 0xed, + 0x6c, 0xcd, 0xd0, 0x1e, 0xe0, 0x8c, 0x1c, 0x5f, 0xbf, 0x9a, 0x13, 0xd9, + 0x37, 0x76, 0x79, 0x0c, 0xf6, 0x41, 0x2f, 0xb3, 0xbc, 0x7d, 0x98, 0xf9, + 0x01, 0x7c, 0x72, 0xc5, 0x8d, 0x60, 0xf0, 0x24, 0x0c, 0x91, 0x2a, 0x4c, + 0x46, 0x22, 0xe8, 0xbe, 0xde, 0x8d, 0x01, 0xef, 0x00, 0x38, 0x00, 0xe5, + 0xc6, 0xf2, 0x94, 0x3c, 0x70, 0xe8, 0xa8, 0x3f, 0x23, 0x1e, 0xc7, 0x8c, + 0x71, 0xd0, 0x85, 0x89, 0x1a, 0xc2, 0x1b, 0x64, 0xab, 0xaf, 0x13, 0x8d, + 0x67, 0x78, 0x26, 0x5c, 0x90, 0x7e, 0x78, 0x04, 0xc1, 0x61, 0x39, 0x70, + 0x58, 0xfe, 0xcb, 0x12, 0x5c, 0x2b, 0x44, 0xf3, 0xe1, 0x29, 0x72, 0x6d, + 0x10, 0xe9, 0xc6, 0x89, 0x8c, 0x30, 0x0a, 0xd7, 0x27, 0x23, 0x11, 0xb8, + 0x88, 0x88, 0xdd, 0x40, 0x61, 0xb1, 0x6c, 0x3a, 0x9a, 0x5e, 0x73, 0x20, + 0xdc, 0x00, 0xc9, 0x72, 0x69, 0x72, 0x1e, 0xa7, 0xfe, 0x58, 0x55, 0x90, + 0xdc, 0x62, 0x62, 0xdb, 0x4c, 0xdc, 0x5c, 0x5c, 0x24, 0x83, 0xd6, 0x80, + 0xc0, 0x17, 0x13, 0x30, 0xc6, 0x8c, 0x38, 0xf9, 0xf9, 0xc9, 0xac, 0x98, + 0x35, 0xfa, 0x20, 0x0c, 0x0f, 0xe3, 0x63, 0xb9, 0xe6, 0xeb, 0xad, 0x88, + 0x3c, 0x08, 0x67, 0xc5, 0x9b, 0xa2, 0xfa, 0xdb, 0x0c, 0xb3, 0xe6, 0xee, + 0xa4, 0xde, 0x41, 0x2f, 0x00, 0x9e, 0x3d, 0x27, 0x82, 0x01, 0xcc, 0x3f, + 0x9a, 0x47, 0xe3, 0x71, 0x97, 0xd0, 0xbe, 0xf3, 0x5c, 0x3b, 0x2c, 0x6f, + 0x1f, 0x66, 0x22, 0xa6, 0xde, 0xee, 0x4f, 0x4a, 0xdf, 0xc8, 0x78, 0x88, + 0x4e, 0x7e, 0x78, 0x52, 0x90, 0xe9, 0xfa, 0x3c, 0xa8, 0x88, 0xc9, 0x5a, + 0xbe, 0x88, 0x64, 0x31, 0xd5, 0xd2, 0x5f, 0xe6, 0x85, 0xeb, 0x1a, 0xad, + 0x0e, 0xdd, 0x17, 0x2f, 0xf1, 0x76, 0x6e, 0x10, 0xd5, 0x1c, 0xcc, 0x66, + 0xcc, 0xf4, 0x15, 0x4b, 0xcd, 0x38, 0xa8, 0xd5, 0x2f, 0xb3, 0xff, 0x7c, + 0x45, 0x5b, 0xa1, 0xc5, 0xd8, 0xd0, 0x08, 0x1f, 0xd3, 0xd6, 0x0d, 0xa2, + 0x28, 0x06, 0x8c, 0x7c, 0xe5, 0x93, 0xed, 0xa8, 0x75, 0x7f, 0x15, 0x3a, + 0xdf, 0x2c, 0x4e, 0x7e, 0x3a, 0xce, 0xc7, 0xab, 0x14, 0x3b, 0x6a, 0x3a, + 0x6a, 0x76, 0xef, 0x66, 0x9e, 0x5d, 0x8c, 0x99, 0x0e, 0x1e, 0x60, 0xa3, + 0xef, 0xbf, 0xc0, 0x6e, 0x0c, 0x7a, 0x59, 0xe7, 0xb9, 0x76, 0x11, 0x63, + 0x74, 0x5f, 0xf3, 0xc0, 0x74, 0x6b, 0x9a, 0x6a, 0x1a, 0xcc, 0x08, 0x06, + 0x03, 0x00, 0x80, 0xa9, 0x6b, 0x21, 0x44, 0x87, 0xc2, 0x88, 0x3e, 0x08, + 0xe3, 0xf4, 0x07, 0x2d, 0x92, 0x0c, 0xd3, 0x7a, 0xa4, 0x55, 0xf8, 0x7f, + 0xb6, 0x75, 0x1b, 0x6a, 0x6a, 0xcd, 0xa8, 0x6b, 0x70, 0x20, 0xbe, 0x1e, + 0x07, 0x07, 0x0e, 0x7a, 0xbd, 0x01, 0x49, 0xe6, 0x13, 0xb5, 0x8f, 0x84, + 0x65, 0xf5, 0xb5, 0xe9, 0x2d, 0xc0, 0x76, 0x7d, 0x4d, 0x45, 0xb9, 0xd0, + 0x2a, 0xd9, 0x3e, 0x93, 0xc9, 0x20, 0x5c, 0x17, 0xcb, 0x69, 0xf9, 0xf8, + 0x2c, 0xb3, 0x5c, 0xef, 0x65, 0x97, 0xae, 0xf7, 0x32, 0xcb, 0xf5, 0x5e, + 0xd6, 0xd1, 0xe9, 0x66, 0xc9, 0x89, 0xc2, 0xeb, 0x9f, 0x6d, 0x8f, 0x1f, + 0x80, 0xde, 0x3d, 0x4c, 0x35, 0x0d, 0x66, 0xe8, 0x82, 0x5a, 0x68, 0x2a, + 0xca, 0xf9, 0xb8, 0x3e, 0x6d, 0x1c, 0x52, 0xfd, 0xf1, 0x2b, 0x4e, 0x21, + 0xfa, 0x65, 0xf6, 0xcf, 0xd5, 0x73, 0x88, 0x8e, 0x87, 0xd1, 0xf2, 0x45, + 0x84, 0x85, 0xbe, 0x88, 0xb0, 0x4c, 0x74, 0x7d, 0x1e, 0x64, 0x9b, 0xcf, + 0xef, 0x62, 0x65, 0x9b, 0x89, 0x0d, 0x8a, 0x2c, 0x03, 0x88, 0x6d, 0x33, + 0x5a, 0x81, 0xe8, 0x8b, 0x65, 0xef, 0x30, 0x93, 0xa5, 0x75, 0x3f, 0x70, + 0xfb, 0x9f, 0x97, 0x00, 0x4d, 0xe1, 0xf2, 0x93, 0x78, 0x36, 0x98, 0x3f, + 0x44, 0x70, 0xd1, 0xf6, 0x12, 0x93, 0xa7, 0x5e, 0xdd, 0xbf, 0xd4, 0xc1, + 0x0f, 0xbf, 0xa0, 0xe7, 0x37, 0xeb, 0x6b, 0x68, 0xba, 0xd8, 0x04, 0x20, + 0xc5, 0x98, 0x5e, 0xf3, 0x2e, 0xb6, 0xb6, 0x9b, 0x31, 0x0f, 0x63, 0xcc, + 0xde, 0xd8, 0xc4, 0x26, 0xf4, 0x93, 0x42, 0x7d, 0x73, 0xb5, 0x19, 0x7e, + 0x00, 0x6b, 0xbb, 0x19, 0xe3, 0xea, 0xf9, 0xc1, 0x4f, 0x97, 0x97, 0xfc, + 0xf7, 0x40, 0x7d, 0xbf, 0xd0, 0xef, 0x92, 0x29, 0xc5, 0x7a, 0x9e, 0x41, + 0xaf, 0xec, 0x44, 0x73, 0x7c, 0xdc, 0x28, 0xb4, 0xbf, 0x54, 0xdb, 0x29, + 0x48, 0x4d, 0xca, 0xf7, 0xc7, 0xfc, 0x7c, 0xfd, 0x99, 0xcc, 0xfe, 0x94, + 0x4f, 0x64, 0x5e, 0xff, 0x54, 0xfb, 0xa4, 0x3d, 0xae, 0x15, 0xa2, 0x53, + 0x83, 0x7c, 0xdc, 0x1d, 0xa8, 0x08, 0x20, 0x70, 0x67, 0x04, 0x9e, 0xbd, + 0x4c, 0x18, 0x87, 0xc6, 0x86, 0x46, 0x91, 0x7d, 0xa8, 0x46, 0x41, 0xfa, + 0x99, 0x4d, 0xe2, 0xfe, 0x3b, 0x4e, 0x9c, 0x11, 0x31, 0x7d, 0xe6, 0x4a, + 0x99, 0xfc, 0x77, 0x19, 0x50, 0x8e, 0xa2, 0x19, 0xf0, 0x47, 0x23, 0x70, + 0x18, 0x0d, 0xc8, 0x55, 0x1c, 0x46, 0x03, 0xe8, 0x04, 0x30, 0xfc, 0xab, + 0xe2, 0x19, 0x77, 0xe0, 0xcf, 0xb9, 0x1d, 0xb6, 0xa6, 0xd6, 0x0c, 0xff, + 0xf1, 0x51, 0xd4, 0xd4, 0x9a, 0x51, 0xe5, 0x09, 0xd1, 0xe8, 0x40, 0x3f, + 0x1f, 0x23, 0x25, 0x88, 0x5c, 0x44, 0x14, 0x19, 0x0f, 0x91, 0xe9, 0xd6, + 0xb4, 0x68, 0x69, 0x6a, 0xd6, 0x37, 0xa3, 0xb5, 0x56, 0xcc, 0x98, 0x88, + 0x88, 0xe5, 0x9e, 0x39, 0xd5, 0x42, 0xc9, 0x94, 0x4c, 0x3a, 0xc3, 0xf8, + 0x01, 0x74, 0x9c, 0x3b, 0x23, 0xb2, 0x37, 0xc9, 0x20, 0xda, 0x0a, 0x2d, + 0x0c, 0x47, 0x74, 0x42, 0x3d, 0xcf, 0x55, 0x8f, 0x70, 0x3d, 0x18, 0x0c, + 0xa0, 0xca, 0x13, 0xa2, 0xe4, 0xae, 0x38, 0xe9, 0x30, 0x47, 0x8f, 0x34, + 0x90, 0xf1, 0x91, 0x51, 0x68, 0x6f, 0x3e, 0x56, 0xa3, 0x38, 0x66, 0x54, + 0xb3, 0x02, 0x61, 0x26, 0x43, 0xdf, 0x6d, 0x7b, 0x46, 0xfe, 0x34, 0x22, + 0xbb, 0x22, 0xb8, 0x88, 0xc8, 0xd1, 0xd0, 0x58, 0x70, 0x4c, 0x9b, 0x19, + 0x33, 0x8f, 0x9c, 0xf7, 0x09, 0xd7, 0x2d, 0xbf, 0xb4, 0x89, 0xb2, 0x25, + 0xba, 0x04, 0x91, 0x7d, 0x7c, 0x95, 0xea, 0x0e, 0x59, 0xa9, 0xfb, 0x6d, + 0x4f, 0x2a, 0x7b, 0xe0, 0x2c, 0x34, 0x6b, 0x90, 0xc4, 0x1f, 0x8d, 0x80, + 0x7e, 0x53, 0x07, 0xb5, 0x85, 0x5d, 0x0b, 0x00, 0xcb, 0xb6, 0x82, 0xfa, + 0x6d, 0x79, 0xcf, 0x01, 0xe3, 0x2b, 0xd2, 0x33, 0x52, 0x93, 0xd8, 0xa0, + 0xa6, 0xf7, 0x8f, 0xca, 0xe6, 0x58, 0xa5, 0x8a, 0x71, 0x8f, 0x11, 0x97, + 0xda, 0x3a, 0x50, 0xb5, 0xa7, 0x0a, 0x8e, 0x06, 0x71, 0x7e, 0x56, 0xaf, + 0x37, 0x60, 0x73, 0xfd, 0x1b, 0xc9, 0x98, 0x2e, 0x33, 0x06, 0x34, 0xb5, + 0x4d, 0x53, 0xd3, 0x9d, 0x26, 0x51, 0x9d, 0x64, 0x6c, 0x27, 0x9a, 0x58, + 0x2b, 0x44, 0x36, 0xa7, 0x74, 0xfe, 0x33, 0xbd, 0xe8, 0xf5, 0x06, 0x78, + 0x2e, 0x77, 0x41, 0xbb, 0x97, 0x8f, 0xe1, 0x3d, 0x69, 0xb9, 0x55, 0xa9, + 0x98, 0x51, 0xaf, 0x37, 0xa0, 0x71, 0x78, 0x34, 0x6f, 0x76, 0x25, 0x73, + 0x82, 0x0b, 0xf6, 0x24, 0x63, 0xfa, 0xed, 0x34, 0x54, 0xba, 0xcd, 0x4a, + 0xc6, 0x61, 0xe0, 0xb0, 0x5d, 0x98, 0xd4, 0x52, 0xfa, 0x25, 0x63, 0xf3, + 0x4c, 0x3d, 0xd2, 0xf7, 0x04, 0x72, 0xc5, 0xb8, 0xc7, 0x08, 0x9f, 0x77, + 0x00, 0x1e, 0xc6, 0x18, 0xeb, 0xba, 0x4f, 0x74, 0xf2, 0xee, 0x36, 0x93, + 0xc5, 0xd4, 0xa1, 0xfd, 0x9f, 0xc2, 0x18, 0x79, 0x47, 0x79, 0x20, 0x9d, + 0x59, 0x5a, 0x83, 0x51, 0xb8, 0xff, 0x5a, 0xa3, 0xba, 0x5f, 0xeb, 0x37, + 0x80, 0xef, 0x5d, 0x96, 0x73, 0x33, 0xe6, 0x5a, 0x21, 0xba, 0xf4, 0xe9, + 0x25, 0x18, 0x61, 0x44, 0x72, 0xa9, 0x03, 0xf8, 0x19, 0xed, 0x87, 0x1f, + 0xa7, 0xeb, 0x4f, 0x23, 0x86, 0x18, 0x3a, 0x8e, 0x9c, 0x81, 0x67, 0xaf, + 0x38, 0xdd, 0x35, 0xe0, 0x1d, 0x80, 0x76, 0x59, 0x0b, 0xff, 0x8c, 0x1f, + 0x5c, 0x35, 0x87, 0xd1, 0xe5, 0x20, 0x2e, 0x1d, 0x69, 0x47, 0x0c, 0x31, + 0x18, 0xd6, 0xab, 0xe0, 0x8f, 0xf9, 0xe1, 0xac, 0x6d, 0x40, 0xf9, 0x6b, + 0xe5, 0x58, 0x7b, 0x3e, 0xa5, 0x87, 0x2e, 0x41, 0x14, 0xfe, 0x9f, 0x28, + 0xba, 0xff, 0xe8, 0x06, 0x57, 0xcd, 0x21, 0x86, 0x18, 0x5c, 0x2d, 0xa7, + 0x64, 0xf5, 0x9c, 0x18, 0x1a, 0x26, 0xc3, 0x66, 0x95, 0x50, 0x3f, 0xd9, + 0x5f, 0x0c, 0x31, 0xb4, 0xfe, 0xaa, 0x35, 0xeb, 0x41, 0xc5, 0xc4, 0xd0, + 0x30, 0xe1, 0x11, 0x30, 0xba, 0x1c, 0x4c, 0x6d, 0xa6, 0x88, 0xc8, 0x75, + 0xdc, 0x05, 0xae, 0x9a, 0x43, 0x79, 0xad, 0x0e, 0xa6, 0x83, 0x07, 0x54, + 0x3f, 0x48, 0xe9, 0xfe, 0xcc, 0x03, 0x67, 0x6d, 0x03, 0xbc, 0xe6, 0x5d, + 0xa2, 0x71, 0xe8, 0xbe, 0xe6, 0x41, 0xe5, 0xba, 0x5e, 0xd0, 0x6b, 0x72, + 0x3d, 0x82, 0xd3, 0xf5, 0x2d, 0x28, 0x47, 0x39, 0x96, 0xd6, 0xd7, 0x84, + 0x71, 0x48, 0xb6, 0xcb, 0xa7, 0x1f, 0xf6, 0x20, 0x2d, 0xb6, 0xcf, 0x9e, + 0x40, 0x99, 0xfd, 0xf9, 0x67, 0xfc, 0x68, 0x7e, 0xb3, 0x05, 0x66, 0x7d, + 0x0d, 0xd6, 0x0e, 0xa6, 0xc6, 0x19, 0x05, 0x9d, 0x7b, 0x75, 0xf3, 0xa7, + 0xb6, 0x76, 0xa2, 0x84, 0xe6, 0x56, 0x09, 0xdd, 0xea, 0xfa, 0xd7, 0x5e, + 0x78, 0xf6, 0x0f, 0xb7, 0x94, 0xf0, 0x29, 0x9e, 0x3d, 0x50, 0x7b, 0x16, + 0xe0, 0x46, 0x94, 0xf2, 0x9e, 0xe6, 0x52, 0x5d, 0x12, 0x44, 0xed, 0x61, + 0x75, 0x7a, 0xe4, 0x32, 0x8c, 0xb6, 0x88, 0x16, 0x13, 0x44, 0x2d, 0xf7, + 0x88, 0xac, 0xf7, 0xf9, 0x97, 0x29, 0x17, 0x13, 0x54, 0x7a, 0x2b, 0xf8, + 0x1f, 0x04, 0x19, 0xda, 0x6e, 0x93, 0xa2, 0x58, 0x52, 0xe3, 0x03, 0x7d, + 0xc4, 0x3f, 0xb2, 0x7c, 0x5a, 0x65, 0x62, 0x09, 0x38, 0x70, 0x5d, 0x59, + 0x6c, 0x7b, 0xe3, 0x63, 0xf9, 0x27, 0x63, 0x1d, 0x57, 0x89, 0x1e, 0xc7, + 0x25, 0xf2, 0xc9, 0x7a, 0x07, 0x9a, 0xdf, 0xcf, 0xff, 0x44, 0x2d, 0x17, + 0x6a, 0xb6, 0x88, 0xca, 0x7f, 0x00, 0x4c, 0x3c, 0x59, 0x83, 0xe5, 0x65, + 0x9d, 0x64, 0x9e, 0xd5, 0x45, 0x44, 0xc9, 0xeb, 0x13, 0x4f, 0xd6, 0x60, + 0x7c, 0xe5, 0x05, 0xd5, 0x79, 0xe5, 0x5c, 0xfd, 0x6f, 0x3e, 0x97, 0x1d, + 0x1a, 0xc5, 0x16, 0x56, 0x49, 0xab, 0xd1, 0xc1, 0x3f, 0x13, 0x05, 0xaa, + 0x6b, 0x60, 0x8a, 0x2f, 0xc1, 0xb2, 0x77, 0x77, 0xd1, 0xfd, 0x7a, 0xef, + 0xcf, 0x51, 0x58, 0x5b, 0x85, 0xf9, 0xc9, 0x00, 0xba, 0xde, 0xb2, 0x01, + 0x58, 0x83, 0xe1, 0xa5, 0x94, 0x3d, 0x13, 0xb3, 0x8b, 0xe4, 0x9e, 0x34, + 0x00, 0x08, 0x00, 0xb0, 0x01, 0x08, 0xc0, 0xf6, 0x96, 0x0d, 0x2e, 0xcd, + 0x37, 0xd0, 0x6c, 0x9f, 0x15, 0x50, 0xd3, 0xdf, 0xd2, 0xca, 0x2a, 0xf9, + 0xa1, 0x43, 0xe0, 0x6e, 0x4a, 0x9e, 0xce, 0x64, 0x43, 0x57, 0x65, 0x4a, + 0x9e, 0x32, 0xa6, 0xed, 0x1e, 0xde, 0x61, 0x6a, 0x95, 0x2f, 0x73, 0xab, + 0xc5, 0x33, 0x6d, 0xa1, 0xed, 0x94, 0x60, 0xfb, 0xb8, 0x58, 0x1e, 0x91, + 0x38, 0x54, 0x21, 0x92, 0xee, 0x37, 0xb4, 0x50, 0xfc, 0x29, 0xb1, 0xe4, + 0xdb, 0xcf, 0xa6, 0x1e, 0xf1, 0x8a, 0x41, 0x09, 0xe9, 0x73, 0xca, 0xa1, + 0x85, 0xe2, 0x56, 0x96, 0xae, 0xfb, 0xd9, 0x72, 0xb5, 0x43, 0x62, 0x3b, + 0xfa, 0x1f, 0xca, 0xdf, 0xa7, 0x96, 0x7b, 0xca, 0x8f, 0x7b, 0x12, 0x11, + 0x71, 0xb7, 0xe4, 0x4f, 0x03, 0xa6, 0x8f, 0x73, 0x59, 0xde, 0xfc, 0xe8, + 0xbc, 0xaf, 0xa0, 0xec, 0x40, 0xa1, 0xa5, 0x4a, 0x07, 0xcc, 0xfd, 0x5b, + 0xfe, 0x7c, 0x6d, 0xae, 0x19, 0x5b, 0x68, 0x3b, 0x25, 0x78, 0x36, 0x28, + 0x96, 0xd7, 0xf1, 0xbf, 0x51, 0x71, 0x7e, 0xf5, 0x0f, 0x13, 0x92, 0xfd, + 0x1e, 0xb8, 0xe9, 0xc3, 0x40, 0x1f, 0x91, 0x46, 0xc1, 0xa1, 0x1f, 0x29, + 0xec, 0x7e, 0x30, 0x8f, 0xf8, 0x26, 0x2f, 0x2f, 0xb2, 0x9c, 0x61, 0xef, + 0x0f, 0x21, 0x69, 0x6f, 0x40, 0x53, 0x1c, 0xb3, 0xaf, 0x55, 0x66, 0xcb, + 0x8d, 0x47, 0xc4, 0x79, 0x72, 0xae, 0x1a, 0xb0, 0x56, 0x4a, 0x8f, 0xb7, + 0x7b, 0xd2, 0x8c, 0x37, 0x7a, 0xc6, 0xf2, 0xe6, 0xcb, 0x5d, 0x44, 0x54, + 0xf5, 0x5f, 0x23, 0xf0, 0xc7, 0x2c, 0x92, 0x72, 0x42, 0xef, 0x39, 0x44, + 0x2b, 0x5a, 0x59, 0xbe, 0xbc, 0xe8, 0xd3, 0x08, 0x09, 0xa2, 0x5f, 0x03, + 0x1d, 0x11, 0xc0, 0x27, 0x93, 0x95, 0x12, 0x1c, 0x37, 0xd7, 0xe9, 0x32, + 0x99, 0x01, 0xe0, 0x77, 0x97, 0x85, 0xb5, 0x53, 0x82, 0xd9, 0xa7, 0xdc, + 0x6a, 0x32, 0x6e, 0xb4, 0x45, 0xb6, 0xff, 0xe0, 0x63, 0x1f, 0x0e, 0xfc, + 0x09, 0x58, 0x5a, 0x51, 0xef, 0xb8, 0xd6, 0xca, 0x2a, 0x59, 0x3b, 0x26, + 0x9e, 0x64, 0xeb, 0x05, 0xa3, 0x43, 0x94, 0x47, 0x2e, 0x04, 0x31, 0x23, + 0x2d, 0x77, 0xe2, 0x49, 0xaa, 0xde, 0xe6, 0x73, 0x8c, 0x35, 0xbe, 0xcb, + 0xd8, 0xe2, 0x07, 0x0e, 0x68, 0x35, 0xd9, 0x76, 0x47, 0x74, 0x36, 0xe8, + 0x2e, 0xfa, 0xd0, 0xb0, 0x25, 0xed, 0xb8, 0xf6, 0x04, 0x91, 0xee, 0xa2, + 0x0f, 0x8f, 0x0d, 0x75, 0x59, 0xfd, 0x54, 0x6a, 0x47, 0x40, 0xe7, 0x1c, + 0x88, 0x65, 0xa4, 0x37, 0xcb, 0x2a, 0x97, 0x46, 0x20, 0xc7, 0x4c, 0xa6, + 0xd7, 0x9e, 0x4e, 0x0c, 0x5b, 0xf3, 0x22, 0x70, 0xf6, 0x8e, 0x0f, 0xff, + 0xfa, 0x07, 0x80, 0xfd, 0x6e, 0x04, 0x97, 0xd6, 0x80, 0xa5, 0xbf, 0x7d, + 0x23, 0xaa, 0x53, 0xa5, 0x03, 0xec, 0xbf, 0x90, 0xd1, 0x4b, 0xff, 0xed, + 0x31, 0x6d, 0x96, 0xbc, 0x99, 0x68, 0xc6, 0xf5, 0x40, 0xce, 0xfe, 0x23, + 0x41, 0x1f, 0x0e, 0xdc, 0xe4, 0x63, 0x50, 0x55, 0xfd, 0xcf, 0x44, 0x65, + 0xed, 0xb0, 0xbc, 0x9c, 0xad, 0x17, 0x62, 0x3e, 0x70, 0xd5, 0x45, 0xc6, + 0xd0, 0xd5, 0xd2, 0x72, 0x2d, 0x2f, 0x67, 0xd7, 0x1f, 0x7d, 0x9e, 0xb1, + 0xb5, 0x8f, 0x1c, 0x30, 0xad, 0x65, 0xdb, 0x1f, 0xdf, 0x74, 0x60, 0xd7, + 0x7f, 0xfa, 0xd0, 0x71, 0x95, 0xa8, 0x7b, 0x7c, 0x9a, 0x96, 0x56, 0x88, + 0x3e, 0xb9, 0x37, 0x45, 0x1d, 0x57, 0xf9, 0x33, 0x2f, 0xc9, 0x15, 0x24, + 0xbd, 0x5d, 0x8b, 0x36, 0x8c, 0xf9, 0x7f, 0xaf, 0x93, 0xdc, 0x33, 0xf0, + 0x71, 0x8b, 0x54, 0x4c, 0x32, 0x44, 0x92, 0x59, 0x82, 0xd5, 0x0d, 0x22, + 0xbb, 0x9f, 0x08, 0xe3, 0xfc, 0xbb, 0x61, 0xb8, 0x45, 0x84, 0x3e, 0xf5, + 0xb1, 0x2b, 0x02, 0x12, 0xfd, 0xf6, 0x85, 0xc4, 0x95, 0x12, 0x44, 0x18, + 0xcd, 0xae, 0xc7, 0xdd, 0xca, 0x1d, 0xab, 0x3d, 0xcd, 0x98, 0x36, 0x53, + 0xde, 0x74, 0xc6, 0xab, 0x25, 0xb2, 0xe3, 0x29, 0x81, 0xfd, 0x0f, 0x95, + 0xc7, 0x9c, 0xd3, 0x2b, 0xf2, 0x76, 0xd0, 0x82, 0x74, 0x4c, 0x5b, 0xec, + 0x77, 0x24, 0xda, 0xc7, 0xa7, 0x25, 0xe5, 0x52, 0x9e, 0x58, 0xb9, 0x7d, + 0x5c, 0xdd, 0xbb, 0x80, 0x99, 0x31, 0x73, 0x3e, 0xf9, 0x65, 0x6b, 0x9b, + 0xe2, 0x19, 0x9c, 0x44, 0xfb, 0xff, 0x85, 0xf9, 0x58, 0x69, 0xbb, 0xb4, + 0x06, 0xa3, 0x60, 0x97, 0x81, 0x17, 0x3a, 0x7d, 0x18, 0xfd, 0x33, 0x80, + 0xa0, 0x0f, 0xd8, 0x9e, 0x21, 0xa1, 0x37, 0xa1, 0xbe, 0x3c, 0x92, 0x60, + 0xa4, 0xc7, 0x16, 0xb0, 0x8b, 0xbe, 0x54, 0x9d, 0x1f, 0x02, 0xf6, 0xcd, + 0x70, 0x56, 0xbd, 0xf6, 0x43, 0x79, 0x96, 0xf0, 0x6f, 0x91, 0x69, 0x7d, + 0x79, 0x98, 0x36, 0x1d, 0x9b, 0x3e, 0xe3, 0xcf, 0x31, 0x17, 0xcb, 0xb4, + 0x90, 0x61, 0x5a, 0x64, 0x84, 0x2e, 0xaa, 0x43, 0xa1, 0xea, 0x1a, 0x69, + 0xb9, 0x12, 0x4c, 0x9b, 0x8e, 0xcd, 0x07, 0x19, 0x0b, 0xbd, 0xbe, 0x06, + 0xad, 0xca, 0xb3, 0x26, 0x26, 0xbd, 0x03, 0x8b, 0x3f, 0x07, 0xd6, 0x5e, + 0xc9, 0xfd, 0xe0, 0x48, 0x76, 0xb7, 0x2b, 0x62, 0xc5, 0xee, 0xe1, 0x9c, + 0x33, 0xe4, 0x76, 0xb4, 0x00, 0xa6, 0x1d, 0xcf, 0x3d, 0xe3, 0xe6, 0x56, + 0x53, 0xcc, 0xae, 0x76, 0x57, 0xfc, 0x6d, 0x32, 0x6d, 0xe6, 0x3b, 0x76, + 0xa6, 0x71, 0xfe, 0xbb, 0x67, 0x44, 0x7c, 0x3d, 0x22, 0x9e, 0x01, 0xd3, + 0xdf, 0x76, 0xe6, 0x6e, 0x85, 0x84, 0xeb, 0x85, 0x30, 0x6d, 0x48, 0x96, + 0x69, 0x8b, 0xcb, 0x1e, 0xc8, 0x31, 0xa6, 0xd2, 0xac, 0x84, 0x9a, 0xb7, + 0xba, 0x2b, 0xef, 0x91, 0xe2, 0x3c, 0x7a, 0x99, 0x87, 0x31, 0x26, 0xe9, + 0xf9, 0xdb, 0x85, 0xfd, 0x6e, 0x04, 0xf8, 0x6b, 0x5d, 0xce, 0x19, 0xe2, + 0x30, 0x42, 0x7d, 0xc9, 0xc3, 0x48, 0xaf, 0xfe, 0xb7, 0x0f, 0x66, 0x2f, + 0xf0, 0xc2, 0xa7, 0xe2, 0x7a, 0xda, 0x79, 0x1f, 0x8c, 0xf9, 0x66, 0xe2, + 0x33, 0x14, 0xd3, 0x86, 0x5e, 0x07, 0x2c, 0x7b, 0x99, 0x70, 0x1c, 0xd0, + 0xc3, 0x18, 0x6b, 0x3e, 0xf8, 0x63, 0xb6, 0xf8, 0x73, 0x80, 0x7b, 0x87, + 0xaf, 0xe7, 0x8f, 0x59, 0x60, 0xbe, 0x16, 0xc8, 0x79, 0x7a, 0xad, 0xf7, + 0x4b, 0xf1, 0x8a, 0x93, 0x7e, 0xfd, 0x59, 0x88, 0x69, 0x25, 0xef, 0xc3, + 0x8b, 0x40, 0x3c, 0xa2, 0x94, 0x69, 0x47, 0x80, 0x1f, 0x28, 0x93, 0x5b, + 0xc6, 0x01, 0xe0, 0x8c, 0xc8, 0xda, 0xf5, 0x8d, 0xcc, 0x03, 0xec, 0xf2, + 0x08, 0xf0, 0x62, 0xf6, 0xae, 0x4e, 0x84, 0x3f, 0x2b, 0x70, 0xb3, 0x66, + 0xb4, 0xe5, 0x96, 0x9b, 0x3c, 0xa7, 0xab, 0x13, 0xd7, 0xeb, 0x7f, 0x27, + 0xbf, 0xe3, 0x7d, 0x9b, 0xd9, 0x03, 0x47, 0x9a, 0x5d, 0xd6, 0xca, 0x00, + 0xa4, 0x1e, 0x04, 0xf8, 0xc1, 0xef, 0xba, 0xed, 0x3f, 0x61, 0x2c, 0xf4, + 0x5e, 0x6a, 0x97, 0xcd, 0xce, 0xfb, 0x60, 0x5c, 0xe0, 0x4f, 0xa3, 0x25, + 0xeb, 0xb9, 0x88, 0xc8, 0x7b, 0x9f, 0xc8, 0x1d, 0x37, 0xcb, 0xda, 0x01, + 0x99, 0xec, 0x41, 0xe6, 0x84, 0x52, 0x8d, 0x33, 0x51, 0xe9, 0x71, 0x7c, + 0x92, 0xbf, 0xbd, 0x8b, 0xf8, 0xac, 0x80, 0xd2, 0xd3, 0x7b, 0x8f, 0x0d, + 0x75, 0x79, 0x27, 0x6e, 0x12, 0xcb, 0xfc, 0x00, 0x7c, 0xbf, 0x40, 0x96, + 0xe7, 0x1f, 0xfe, 0xd4, 0x07, 0xac, 0xe7, 0x66, 0x58, 0xc0, 0x01, 0x3c, + 0x99, 0x90, 0xf5, 0xcb, 0x9c, 0x45, 0x45, 0xec, 0x97, 0x8e, 0x3a, 0xcd, + 0x5a, 0x7e, 0xc7, 0xca, 0xd1, 0x7e, 0x33, 0xb1, 0x51, 0x50, 0x9e, 0x54, + 0x29, 0xd3, 0x8a, 0x63, 0x5a, 0x5b, 0x5e, 0x79, 0xb1, 0x57, 0x18, 0xdb, + 0xf8, 0x0f, 0x7e, 0x05, 0x49, 0xe6, 0x73, 0xd9, 0x15, 0xe0, 0x85, 0xb6, + 0xdb, 0x74, 0xb4, 0x8d, 0x88, 0x9d, 0xf7, 0xe1, 0xe4, 0x5d, 0x89, 0x7e, + 0xd3, 0xed, 0x7d, 0x4a, 0x31, 0x6d, 0xbc, 0x52, 0x7d, 0x4c, 0xab, 0xd9, + 0x22, 0x32, 0x2e, 0xf0, 0x7a, 0x4b, 0x65, 0x05, 0x72, 0x61, 0x64, 0x99, + 0x4f, 0x8f, 0xd9, 0x13, 0xb9, 0x1d, 0xb7, 0x2c, 0xb9, 0x64, 0x55, 0xee, + 0x57, 0x36, 0x23, 0x32, 0x71, 0xf8, 0x67, 0x16, 0x59, 0xbf, 0xcc, 0x59, + 0x14, 0x30, 0x6d, 0x26, 0x5a, 0x2b, 0xa1, 0xe8, 0x91, 0x68, 0x4e, 0x39, + 0x28, 0x7f, 0xaa, 0x4c, 0x2b, 0xb6, 0x4b, 0x99, 0x5c, 0xef, 0x73, 0x7c, + 0xba, 0x48, 0x2a, 0xcf, 0xa9, 0x64, 0xc5, 0x88, 0x7e, 0x9d, 0xad, 0x17, + 0x8c, 0x0e, 0x04, 0xee, 0x16, 0x17, 0x0a, 0xf9, 0x3e, 0x1b, 0x91, 0x94, + 0x2b, 0xf7, 0x8a, 0x90, 0x6e, 0x81, 0xa8, 0xe6, 0x73, 0xe0, 0xc0, 0x4d, + 0x69, 0xbd, 0x4d, 0x7a, 0x60, 0xfa, 0x84, 0x03, 0xed, 0xd6, 0x28, 0x42, + 0xef, 0xf1, 0x79, 0xd8, 0xcc, 0x7a, 0xf1, 0x2a, 0x07, 0x76, 0x5f, 0xf1, + 0x61, 0xf3, 0xbe, 0x78, 0xc5, 0xc9, 0x62, 0x5a, 0x0e, 0x40, 0x87, 0x7e, + 0x1e, 0x85, 0x30, 0xdf, 0xef, 0xbe, 0x0c, 0x4b, 0xfa, 0x64, 0xde, 0x12, + 0x54, 0xd7, 0x0f, 0x62, 0x3e, 0x04, 0x7e, 0xad, 0xd0, 0xb1, 0x72, 0xc8, + 0xd9, 0x7d, 0xc5, 0x87, 0x89, 0x59, 0xa2, 0xd8, 0xc2, 0x6a, 0xde, 0x27, + 0x35, 0x85, 0x30, 0xad, 0x78, 0x05, 0x51, 0x2e, 0xd7, 0xc3, 0xe4, 0xf3, + 0x9c, 0xf9, 0x62, 0x73, 0xc3, 0x4b, 0x8c, 0x49, 0xe5, 0xdb, 0x83, 0x8f, + 0x81, 0xee, 0xf1, 0xe9, 0x82, 0x56, 0x96, 0xd6, 0xa1, 0x29, 0x7a, 0x1c, + 0xcf, 0x5e, 0x69, 0x9d, 0x9a, 0xec, 0x57, 0x84, 0x5c, 0xc4, 0xe7, 0x5d, + 0xd9, 0x4d, 0xe0, 0xf1, 0x64, 0xb6, 0xbe, 0x26, 0xbd, 0x03, 0xa1, 0xd7, + 0xd7, 0x30, 0xf6, 0x3e, 0x63, 0x93, 0x2f, 0xf1, 0x31, 0x7d, 0xec, 0x15, + 0xc6, 0xc2, 0xbf, 0x3d, 0xcc, 0xba, 0x2a, 0xe7, 0x25, 0xb3, 0x0c, 0x27, + 0xef, 0xfa, 0xa0, 0xfb, 0x3d, 0x7f, 0xf6, 0x21, 0xeb, 0xfe, 0xae, 0x22, + 0xb5, 0x2b, 0xb3, 0xf6, 0x8d, 0xa9, 0xcf, 0xaf, 0x8d, 0xab, 0xcf, 0x1c, + 0x90, 0xca, 0x6f, 0x7a, 0xa1, 0xed, 0x36, 0x59, 0xef, 0x2b, 0x7f, 0x76, + 0x5f, 0x48, 0x7e, 0x50, 0x0e, 0xbb, 0xee, 0xf3, 0xbb, 0xff, 0xa4, 0x7c, + 0x35, 0x79, 0x5a, 0x35, 0x5f, 0xc6, 0x49, 0x47, 0xe7, 0x50, 0xfe, 0xf1, + 0xc9, 0x6c, 0x47, 0x24, 0xff, 0x65, 0x76, 0x6b, 0x1f, 0xd1, 0xc6, 0x56, + 0xfe, 0xdd, 0x39, 0x6d, 0xf1, 0xf5, 0x2a, 0xaf, 0x4a, 0x67, 0x8b, 0xa4, + 0x3e, 0xc3, 0x4a, 0x24, 0x5f, 0x5f, 0xe9, 0x99, 0x0b, 0x4a, 0x10, 0x99, + 0x72, 0x64, 0x93, 0xac, 0x7d, 0x24, 0xea, 0x57, 0xf4, 0x85, 0x19, 0x17, + 0xf1, 0xb1, 0x08, 0x9f, 0x3d, 0x50, 0x8e, 0x74, 0x4e, 0xdd, 0x66, 0x4c, + 0xed, 0xf7, 0x10, 0xb4, 0x1a, 0x07, 0xa2, 0x27, 0x94, 0x9f, 0x1a, 0x3a, + 0xda, 0x46, 0x54, 0xc8, 0x1b, 0x11, 0xb9, 0x30, 0x79, 0xaa, 0xec, 0x85, + 0x36, 0xf1, 0xa9, 0xb8, 0x76, 0x6b, 0x14, 0xcd, 0x07, 0x7f, 0x2c, 0xe8, + 0x95, 0xfe, 0xfd, 0x08, 0x6b, 0xa5, 0x03, 0x8d, 0xef, 0x16, 0x76, 0xaa, + 0x6c, 0xf4, 0xe1, 0x1c, 0x35, 0x7d, 0x26, 0xff, 0x16, 0xb3, 0xd4, 0x29, + 0xb7, 0xe4, 0x33, 0xfc, 0xc7, 0xf1, 0x3a, 0xd9, 0x76, 0xd6, 0x4a, 0xfe, + 0xd4, 0x94, 0x29, 0xce, 0x9f, 0x06, 0xc3, 0x4c, 0x14, 0x81, 0xf9, 0x1a, + 0xc4, 0x37, 0x03, 0x88, 0xe4, 0x78, 0x93, 0xc4, 0x5a, 0x19, 0x40, 0xe0, + 0xd7, 0x36, 0x21, 0x34, 0xd0, 0x6c, 0x11, 0x9d, 0x5d, 0x06, 0xdc, 0x37, + 0xa5, 0xeb, 0x6b, 0x35, 0x3e, 0x2c, 0x7e, 0xe0, 0x80, 0xf7, 0x39, 0xe5, + 0xf6, 0x4f, 0xcc, 0x12, 0xf5, 0x0e, 0xe6, 0x97, 0x97, 0xe5, 0xf9, 0x8b, + 0x09, 0xf5, 0x8c, 0xd4, 0x12, 0x98, 0x56, 0x97, 0xa3, 0x75, 0xe7, 0xce, + 0xfb, 0x16, 0xf3, 0xe4, 0x68, 0x15, 0x40, 0xcb, 0xbd, 0xa9, 0x1d, 0x63, + 0xda, 0xcc, 0x27, 0x4b, 0x99, 0x79, 0x58, 0x29, 0xe6, 0x49, 0x9d, 0x72, + 0x2a, 0x2e, 0x4f, 0x4a, 0x0b, 0xd2, 0x0c, 0x64, 0xea, 0xc9, 0xcd, 0xe0, + 0xfd, 0x0f, 0xf9, 0x1c, 0xed, 0x4e, 0xd8, 0xdf, 0xff, 0x50, 0x3a, 0x2f, + 0x9b, 0xeb, 0x74, 0x97, 0xb5, 0xaf, 0xf0, 0x0f, 0x63, 0xe7, 0x5a, 0x31, + 0xd0, 0x76, 0x9b, 0x36, 0xb6, 0x88, 0x24, 0x1b, 0x3a, 0x67, 0xb7, 0x2b, + 0x2a, 0x7d, 0x93, 0xe1, 0x02, 0xff, 0x06, 0x82, 0x92, 0xa2, 0xf6, 0xeb, + 0x89, 0xce, 0xa1, 0xc2, 0xbe, 0x66, 0xb8, 0xb1, 0xc5, 0xf7, 0x17, 0x5a, + 0x58, 0x2d, 0x0a, 0xe5, 0x06, 0x36, 0xdf, 0xf5, 0x9d, 0xfc, 0x0d, 0x89, + 0x4c, 0xbd, 0xd4, 0xb4, 0xeb, 0x7f, 0x38, 0x47, 0xed, 0x2b, 0xbc, 0x23, + 0x59, 0xfb, 0xb6, 0x97, 0x72, 0x99, 0x2f, 0xb0, 0x5b, 0xfb, 0xf8, 0x07, + 0x1d, 0xed, 0x2b, 0xfc, 0xaf, 0x16, 0xe5, 0x72, 0xbc, 0xfe, 0x87, 0x73, + 0x64, 0xed, 0xdb, 0x76, 0xb0, 0x36, 0x5e, 0x3e, 0xf7, 0x90, 0x6f, 0xb7, + 0x13, 0xf6, 0x76, 0xdd, 0xe7, 0xe5, 0x27, 0x7f, 0xe3, 0xa3, 0xf2, 0xea, + 0xb0, 0xf0, 0xdb, 0x1c, 0xb2, 0xb1, 0x4d, 0xae, 0x18, 0x43, 0x12, 0x03, + 0xfc, 0xf7, 0x67, 0x73, 0x95, 0xce, 0x09, 0x75, 0xb1, 0x6c, 0xa1, 0x31, + 0x61, 0x09, 0xff, 0xb1, 0x31, 0x27, 0x53, 0x15, 0xf2, 0x5b, 0x0b, 0xc9, + 0x2f, 0x7f, 0x67, 0x16, 0xd3, 0x40, 0x48, 0x95, 0x1c, 0x25, 0x8f, 0x36, + 0x4b, 0xf8, 0xfd, 0xc4, 0xbc, 0x15, 0x86, 0x67, 0x55, 0x32, 0xee, 0x0e, + 0x60, 0xa1, 0x21, 0x41, 0x09, 0xbf, 0x1f, 0xa8, 0xa8, 0xe2, 0x62, 0x22, + 0x15, 0xbb, 0xa8, 0x65, 0x5e, 0x35, 0xa8, 0xbd, 0xc0, 0xc7, 0x60, 0xcf, + 0xc2, 0xc0, 0x94, 0xf0, 0xd9, 0x45, 0xc5, 0x15, 0x89, 0xb6, 0x83, 0xe2, + 0xa7, 0xc4, 0xb0, 0xd6, 0xfb, 0x44, 0x94, 0x28, 0xbd, 0x2d, 0x5b, 0xc2, + 0xfc, 0xa8, 0xba, 0x41, 0x68, 0x61, 0x95, 0xac, 0x7d, 0x3b, 0xc7, 0xb0, + 0xc5, 0xa4, 0x47, 0x4a, 0xf8, 0xfd, 0xc4, 0x82, 0x1b, 0x12, 0xf1, 0x79, + 0xc8, 0xca, 0x7b, 0xea, 0x99, 0xb5, 0xf2, 0xea, 0x30, 0xff, 0x0b, 0xe5, + 0x25, 0x66, 0x2d, 0x61, 0x01, 0xb8, 0x23, 0x82, 0x92, 0xf9, 0xc0, 0xe9, + 0x15, 0x7e, 0xd7, 0x9f, 0xcc, 0xaf, 0x25, 0x91, 0x7b, 0xc8, 0x27, 0xe8, + 0x37, 0xb6, 0x4a, 0xbf, 0x81, 0x5b, 0xc2, 0xe2, 0xf1, 0xff, 0x01, 0xe7, + 0xc1, 0x25, 0xe6, 0xc2, 0x97, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -844,19 +794,19 @@ ConfigurationPanel::ConfigurationPanel( QWidget* parent, const char* name, bool ConfigurationPanelLayout->addWidget( Menu, 0, 0 ); - layout17 = new QVBoxLayout( 0, 0, 6, "layout17"); + layout19_2 = new QVBoxLayout( 0, 0, 6, "layout19_2"); TitleTab = new QLabel( this, "TitleTab" ); QFont TitleTab_font( TitleTab->font() ); TitleTab_font.setBold( TRUE ); TitleTab->setFont( TitleTab_font ); - layout17->addWidget( TitleTab ); + layout19_2->addWidget( TitleTab ); line2 = new QFrame( this, "line2" ); line2->setFrameShape( QFrame::HLine ); line2->setFrameShadow( QFrame::Sunken ); line2->setFrameShape( QFrame::HLine ); - layout17->addWidget( line2 ); + layout19_2->addWidget( line2 ); Tab_Signalisations = new QTabWidget( this, "Tab_Signalisations" ); @@ -925,17 +875,17 @@ ConfigurationPanel::ConfigurationPanel( QWidget* parent, const char* name, bool layout23 = new QVBoxLayout( 0, 0, 6, "layout23"); - layout19_2 = new QHBoxLayout( 0, 0, 6, "layout19_2"); + layout19_3 = new QHBoxLayout( 0, 0, 6, "layout19_3"); autoregister = new QCheckBox( privateLayoutWidget, "autoregister" ); autoregister->setChecked( TRUE ); - layout19_2->addWidget( autoregister ); + layout19_3->addWidget( autoregister ); spacer7 = new QSpacerItem( 201, 21, QSizePolicy::Expanding, QSizePolicy::Minimum ); - layout19_2->addItem( spacer7 ); + layout19_3->addItem( spacer7 ); Register = new QPushButton( privateLayoutWidget, "Register" ); - layout19_2->addWidget( Register ); - layout23->addLayout( layout19_2 ); + layout19_3->addWidget( Register ); + layout23->addLayout( layout19_3 ); spacer9 = new QSpacerItem( 20, 21, QSizePolicy::Minimum, QSizePolicy::Expanding ); layout23->addItem( spacer9 ); layout24->addLayout( layout23 ); @@ -1017,7 +967,7 @@ ConfigurationPanel::ConfigurationPanel( QWidget* parent, const char* name, bool SettingsDTMFLayout->addLayout( layout11, 0, 0 ); Tab_Signalisations->insertTab( DTMFPage, QString("") ); - layout17->addWidget( Tab_Signalisations ); + layout19_2->addWidget( Tab_Signalisations ); Tab_Audio = new QTabWidget( this, "Tab_Audio" ); @@ -1043,52 +993,37 @@ ConfigurationPanel::ConfigurationPanel( QWidget* parent, const char* name, bool CodecsPage = new QWidget( Tab_Audio, "CodecsPage" ); CodecsChoice = new QButtonGroup( CodecsPage, "CodecsChoice" ); - CodecsChoice->setGeometry( QRect( 20, 10, 126, 196 ) ); - CodecsChoice->setColumnLayout(0, Qt::Vertical ); - CodecsChoice->layout()->setSpacing( 6 ); - CodecsChoice->layout()->setMargin( 11 ); - CodecsChoiceLayout = new QGridLayout( CodecsChoice->layout() ); - CodecsChoiceLayout->setAlignment( Qt::AlignTop ); - - layout11_2 = new QHBoxLayout( 0, 0, 6, "layout11_2"); - - layout9 = new QVBoxLayout( 0, 0, 6, "layout9"); + CodecsChoice->setGeometry( QRect( 20, 10, 133, 157 ) ); - codec1 = new QComboBox( FALSE, CodecsChoice, "codec1" ); - layout9->addWidget( codec1 ); + QWidget* privateLayoutWidget_2 = new QWidget( CodecsChoice, "layout18" ); + privateLayoutWidget_2->setGeometry( QRect( 10, 20, 110, 120 ) ); + layout18 = new QGridLayout( privateLayoutWidget_2, 1, 1, 11, 6, "layout18"); - codec2 = new QComboBox( FALSE, CodecsChoice, "codec2" ); - layout9->addWidget( codec2 ); - - codec3 = new QComboBox( FALSE, CodecsChoice, "codec3" ); - layout9->addWidget( codec3 ); + layout17 = new QVBoxLayout( 0, 0, 6, "layout17"); - codec4 = new QComboBox( FALSE, CodecsChoice, "codec4" ); - layout9->addWidget( codec4 ); + codec1 = new QComboBox( FALSE, privateLayoutWidget_2, "codec1" ); + layout17->addWidget( codec1 ); - codec5 = new QComboBox( FALSE, CodecsChoice, "codec5" ); - layout9->addWidget( codec5 ); - layout11_2->addLayout( layout9 ); + codec2 = new QComboBox( FALSE, privateLayoutWidget_2, "codec2" ); + layout17->addWidget( codec2 ); - layout10_2 = new QVBoxLayout( 0, 0, 6, "layout10_2"); + codec3 = new QComboBox( FALSE, privateLayoutWidget_2, "codec3" ); + layout17->addWidget( codec3 ); - textLabel1_4 = new QLabel( CodecsChoice, "textLabel1_4" ); - layout10_2->addWidget( textLabel1_4 ); + layout18->addLayout( layout17, 0, 0 ); - textLabel1_4_2 = new QLabel( CodecsChoice, "textLabel1_4_2" ); - layout10_2->addWidget( textLabel1_4_2 ); + layout18_2 = new QVBoxLayout( 0, 0, 6, "layout18_2"); - textLabel1_4_3 = new QLabel( CodecsChoice, "textLabel1_4_3" ); - layout10_2->addWidget( textLabel1_4_3 ); + textLabel1_4 = new QLabel( privateLayoutWidget_2, "textLabel1_4" ); + layout18_2->addWidget( textLabel1_4 ); - textLabel1_4_4 = new QLabel( CodecsChoice, "textLabel1_4_4" ); - layout10_2->addWidget( textLabel1_4_4 ); + textLabel1_4_2 = new QLabel( privateLayoutWidget_2, "textLabel1_4_2" ); + layout18_2->addWidget( textLabel1_4_2 ); - textLabel1_4_5 = new QLabel( CodecsChoice, "textLabel1_4_5" ); - layout10_2->addWidget( textLabel1_4_5 ); - layout11_2->addLayout( layout10_2 ); + textLabel1_4_3 = new QLabel( privateLayoutWidget_2, "textLabel1_4_3" ); + layout18_2->addWidget( textLabel1_4_3 ); - CodecsChoiceLayout->addLayout( layout11_2, 0, 0 ); + layout18->addLayout( layout18_2, 0, 1 ); Tab_Audio->insertTab( CodecsPage, QString("") ); RingPage = new QWidget( Tab_Audio, "RingPage" ); @@ -1096,7 +1031,7 @@ ConfigurationPanel::ConfigurationPanel( QWidget* parent, const char* name, bool ringsChoice = new QComboBox( FALSE, RingPage, "ringsChoice" ); ringsChoice->setGeometry( QRect( 20, 21, 150, 30 ) ); Tab_Audio->insertTab( RingPage, QString("") ); - layout17->addWidget( Tab_Audio ); + layout19_2->addWidget( Tab_Audio ); Tab_Preferences = new QTabWidget( this, "Tab_Preferences" ); @@ -1111,40 +1046,40 @@ ConfigurationPanel::ConfigurationPanel( QWidget* parent, const char* name, bool TabPage = new QWidget( Tab_Preferences, "TabPage" ); - QWidget* privateLayoutWidget_2 = new QWidget( TabPage, "layout17" ); - privateLayoutWidget_2->setGeometry( QRect( 10, 10, 262, 200 ) ); - layout17_2 = new QVBoxLayout( privateLayoutWidget_2, 11, 6, "layout17_2"); + QWidget* privateLayoutWidget_3 = new QWidget( TabPage, "layout17" ); + privateLayoutWidget_3->setGeometry( QRect( 10, 10, 262, 200 ) ); + layout17_2 = new QVBoxLayout( privateLayoutWidget_3, 11, 6, "layout17_2"); layout16 = new QHBoxLayout( 0, 0, 6, "layout16"); - textLabel1_2 = new QLabel( privateLayoutWidget_2, "textLabel1_2" ); + textLabel1_2 = new QLabel( privateLayoutWidget_3, "textLabel1_2" ); layout16->addWidget( textLabel1_2 ); - zoneToneChoice = new QComboBox( FALSE, privateLayoutWidget_2, "zoneToneChoice" ); + zoneToneChoice = new QComboBox( FALSE, privateLayoutWidget_3, "zoneToneChoice" ); layout16->addWidget( zoneToneChoice ); spacer5 = new QSpacerItem( 31, 21, QSizePolicy::Expanding, QSizePolicy::Minimum ); layout16->addItem( spacer5 ); layout17_2->addLayout( layout16 ); - confirmationToQuit = new QCheckBox( privateLayoutWidget_2, "confirmationToQuit" ); + confirmationToQuit = new QCheckBox( privateLayoutWidget_3, "confirmationToQuit" ); confirmationToQuit->setChecked( TRUE ); layout17_2->addWidget( confirmationToQuit ); - checkedTray = new QCheckBox( privateLayoutWidget_2, "checkedTray" ); + checkedTray = new QCheckBox( privateLayoutWidget_3, "checkedTray" ); layout17_2->addWidget( checkedTray ); layout16_2 = new QHBoxLayout( 0, 0, 6, "layout16_2"); - textLabel1_6 = new QLabel( privateLayoutWidget_2, "textLabel1_6" ); + textLabel1_6 = new QLabel( privateLayoutWidget_3, "textLabel1_6" ); layout16_2->addWidget( textLabel1_6 ); - voicemailNumber = new QLineEdit( privateLayoutWidget_2, "voicemailNumber" ); + voicemailNumber = new QLineEdit( privateLayoutWidget_3, "voicemailNumber" ); layout16_2->addWidget( voicemailNumber ); spacer6_2 = new QSpacerItem( 61, 21, QSizePolicy::Expanding, QSizePolicy::Minimum ); layout16_2->addItem( spacer6_2 ); layout17_2->addLayout( layout16_2 ); Tab_Preferences->insertTab( TabPage, QString("") ); - layout17->addWidget( Tab_Preferences ); + layout19_2->addWidget( Tab_Preferences ); Tab_About = new QTabWidget( this, "Tab_About" ); @@ -1169,9 +1104,9 @@ ConfigurationPanel::ConfigurationPanel( QWidget* parent, const char* name, bool pixmapLabel2->setPixmap( image1 ); pixmapLabel2->setScaledContents( TRUE ); Tab_About->insertTab( CodecsPage_2, QString("") ); - layout17->addWidget( Tab_About ); + layout19_2->addWidget( Tab_About ); - ConfigurationPanelLayout->addLayout( layout17, 0, 1 ); + ConfigurationPanelLayout->addLayout( layout19_2, 0, 1 ); languageChange(); resize( QSize(561, 552).expandedTo(minimumSizeHint()) ); clearWState( WState_Polished ); @@ -1214,9 +1149,7 @@ ConfigurationPanel::ConfigurationPanel( QWidget* parent, const char* name, bool setTabOrder( ossButton, codec1 ); setTabOrder( codec1, codec2 ); setTabOrder( codec2, codec3 ); - setTabOrder( codec3, codec4 ); - setTabOrder( codec4, codec5 ); - setTabOrder( codec5, Tab_Preferences ); + setTabOrder( codec3, Tab_Preferences ); setTabOrder( Tab_Preferences, Tab_About ); setTabOrder( Tab_About, Register ); setTabOrder( Register, useStunNo ); @@ -1292,19 +1225,9 @@ void ConfigurationPanel::languageChange() codec3->insertItem( tr( "G711u" ) ); codec3->insertItem( tr( "G711a" ) ); codec3->insertItem( tr( "GSM" ) ); - codec4->clear(); - codec4->insertItem( tr( "G711u" ) ); - codec4->insertItem( tr( "G711a" ) ); - codec4->insertItem( tr( "GSM" ) ); - codec5->clear(); - codec5->insertItem( tr( "G711u" ) ); - codec5->insertItem( tr( "G711a" ) ); - codec5->insertItem( tr( "GSM" ) ); textLabel1_4->setText( tr( "1" ) ); textLabel1_4_2->setText( tr( "2" ) ); textLabel1_4_3->setText( tr( "3" ) ); - textLabel1_4_4->setText( tr( "4" ) ); - textLabel1_4_5->setText( tr( "5" ) ); Tab_Audio->changeTab( CodecsPage, tr( "Codecs" ) ); Tab_Audio->changeTab( RingPage, tr( "Ringtones" ) ); buttonApplySkin->setText( tr( "&Apply" ) ); diff --git a/src/gui/qt/configurationpanelui.h b/src/gui/qt/configurationpanelui.h index 0441341e73..069f5dead4 100644 --- a/src/gui/qt/configurationpanelui.h +++ b/src/gui/qt/configurationpanelui.h @@ -1,7 +1,7 @@ /**************************************************************************** ** Form interface generated from reading ui file 'gui/qt/configurationpanel.ui' ** -** Created: Mon May 30 14:35:17 2005 +** Created: Thu Jun 2 11:14:54 2005 ** by: The User Interface Compiler ($Id$) ** ** WARNING! All changes made in this file will be lost! @@ -90,13 +90,9 @@ public: QComboBox* codec1; QComboBox* codec2; QComboBox* codec3; - QComboBox* codec4; - QComboBox* codec5; QLabel* textLabel1_4; QLabel* textLabel1_4_2; QLabel* textLabel1_4_3; - QLabel* textLabel1_4_4; - QLabel* textLabel1_4_5; QWidget* RingPage; QComboBox* ringsChoice; QTabWidget* Tab_Preferences; @@ -130,12 +126,12 @@ protected: QVBoxLayout* layout19; QHBoxLayout* layout28; QSpacerItem* Horizontal_Spacing2; - QVBoxLayout* layout17; + QVBoxLayout* layout19_2; QVBoxLayout* layout24; QGridLayout* groupBox1Layout; QVBoxLayout* layout23; QSpacerItem* spacer9; - QHBoxLayout* layout19_2; + QHBoxLayout* layout19_3; QSpacerItem* spacer7; QVBoxLayout* stunButtonGroupLayout; QGridLayout* SettingsDTMFLayout; @@ -147,10 +143,9 @@ protected: QHBoxLayout* layout8; QSpacerItem* spacer4; QVBoxLayout* DriverChoiceLayout; - QGridLayout* CodecsChoiceLayout; - QHBoxLayout* layout11_2; - QVBoxLayout* layout9; - QVBoxLayout* layout10_2; + QGridLayout* layout18; + QVBoxLayout* layout17; + QVBoxLayout* layout18_2; QVBoxLayout* layout17_2; QHBoxLayout* layout16; QSpacerItem* spacer5; diff --git a/src/gui/qt/qtGUImainwindow.cpp b/src/gui/qt/qtGUImainwindow.cpp index 27eebb746a..b04b81aeb9 100644 --- a/src/gui/qt/qtGUImainwindow.cpp +++ b/src/gui/qt/qtGUImainwindow.cpp @@ -1428,8 +1428,9 @@ void QtGUIMainWindow::pressedKeySlot (int id) { char code = 0; int pulselen = 0; - int a = 0; int callid; + float32* tmp_urg_data; + float32* buf_ctrl_vol; // Stop dial tone if (_dialtone) { @@ -1464,16 +1465,30 @@ QtGUIMainWindow::pressedKeySlot (int id) { pulselen = get_config_fields_int(SIGNALISATION, PULSE_LENGTH); int size = pulselen * (OCTETS/1000); + + // Control volume + buf_ctrl_vol = new float32[size]; + for (int j = 0; j < size; j++) { + buf_ctrl_vol[j] = _buf[j] * _callmanager->getSpkrVolume()/100; + } - _callmanager->getAudioDriver()->mydata.dataToAdd = _buf; - _callmanager->getAudioDriver()->mydata.dataToAddRem = size; - _callmanager->getAudioDriver()->mydata.dataFilled = 0; - - if (!_callmanager->getAudioDriver()->isStreamActive()) { - _callmanager->getAudioDriver()->startStream(); + // Free urg_data pointer + tmp_urg_data = _callmanager->getAudioDriver()->mydata.urg_data; + if (tmp_urg_data != NULL) { + free (tmp_urg_data); } + + // Init struct mydata + tmp_urg_data = buf_ctrl_vol; + _callmanager->getAudioDriver()->mydata.urg_ptr = tmp_urg_data; + _callmanager->getAudioDriver()->mydata.urg_remain = size; + + _callmanager->getAudioDriver()->startStream(); _callmanager->getAudioDriver()->sleep(pulselen); _callmanager->getAudioDriver()->stopStream(); + _callmanager->getAudioDriver()->mydata.urg_remain = 0; + + delete[] buf_ctrl_vol; } // Save settings in config-file diff --git a/src/gui/qt/url_inputui.cpp b/src/gui/qt/url_inputui.cpp index 645486ae01..807502944b 100644 --- a/src/gui/qt/url_inputui.cpp +++ b/src/gui/qt/url_inputui.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** Form implementation generated from reading ui file 'gui/qt/url_input.ui' ** -** Created: Mon May 30 14:35:16 2005 +** Created: Thu Jun 2 11:14:54 2005 ** by: The User Interface Compiler ($Id$) ** ** WARNING! All changes made in this file will be lost! diff --git a/src/gui/qt/url_inputui.h b/src/gui/qt/url_inputui.h index 94ee317cdc..a147bba7d9 100644 --- a/src/gui/qt/url_inputui.h +++ b/src/gui/qt/url_inputui.h @@ -1,7 +1,7 @@ /**************************************************************************** ** Form interface generated from reading ui file 'gui/qt/url_input.ui' ** -** Created: Mon May 30 14:35:16 2005 +** Created: Thu Jun 2 11:14:54 2005 ** by: The User Interface Compiler ($Id$) ** ** WARNING! All changes made in this file will be lost! diff --git a/src/manager.cpp b/src/manager.cpp index f582e24977..f78a4cb5f6 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -446,8 +446,8 @@ Manager::peerAnsweredCall (short id) call = getCall(id); call->setStatus(string(CONNECTED_STATUS)); call->setState(Answered); - _gui->peerAnsweredCall(id); ringback(false); + _gui->peerAnsweredCall(id); displayStatus(CONNECTED_STATUS); return 1; } @@ -460,8 +460,8 @@ Manager::peerRingingCall (short id) call = getCall(id); call->setStatus(string(RINGING_STATUS)); call->setState(Ringing); - _gui->peerRingingCall(id); ringback(true); + _gui->peerRingingCall(id); displayStatus(RINGING_STATUS); return 1; } @@ -551,14 +551,37 @@ Manager::ringtone (bool var) { void Manager::notificationIncomingCall (void) { - float32 *buffer = new float32[SAMPLING_RATE]; + float32* tmp_urg_data; + float32* buf_ctrl_vol; + float32* buffer = new float32[SAMPLING_RATE]; + int size = SAMPLING_RATE/2; - _tone->generateSin(440, 0, SAMPLING_RATE, buffer); - - getAudioDriver()->mydata.dataToAdd = buffer; - getAudioDriver()->mydata.dataToAddRem = SAMPLING_RATE/2; + _tone->generateSin(440, 0, buffer); + + // Control volume + buf_ctrl_vol = new float32[size]; + for (int j = 0; j < size; j++) { + buf_ctrl_vol[j] = buffer[j] * getSpkrVolume()/100; + } + + // Free urg_data pointer + tmp_urg_data = getAudioDriver()->mydata.urg_data; + if (tmp_urg_data != NULL) { + free (tmp_urg_data); + } + + // Init struct mydata + tmp_urg_data = buf_ctrl_vol; + getAudioDriver()->mydata.urg_ptr = tmp_urg_data; + getAudioDriver()->mydata.urg_remain = size; + + getAudioDriver()->startStream(); + getAudioDriver()->sleep(250); + getAudioDriver()->stopStream(); + getAudioDriver()->mydata.urg_remain = 0; delete[] buffer; + delete[] buf_ctrl_vol; } void @@ -694,21 +717,17 @@ Manager::initConfigFile (void) void Manager::initAudioCodec (void) { - _nCodecs = 3;//get_config_fields_int(AUDIO, NB_CODEC); + _nCodecs = get_config_fields_int(AUDIO, NB_CODEC); _codecDescVector = new CodecDescriptorVector(); - _codecDescVector->push_back(new CodecDescriptor(PAYLOAD_CODEC_ULAW, - CODEC_ULAW)); - _codecDescVector->push_back(new CodecDescriptor(PAYLOAD_CODEC_ALAW, - CODEC_ALAW)); - _codecDescVector->push_back(new CodecDescriptor(PAYLOAD_CODEC_GSM, - CODEC_GSM)); - // TODO: When these codec will be implemented, remove comment -#if 0 - _codecDescVector->push_back(new CodecDescriptor(PAYLOAD_CODEC_ILBC, - CODEC_ILBC)); - _codecDescVector->push_back(new CodecDescriptor(PAYLOAD_CODEC_SPEEX, - CODEC_SPEEX)); -#endif + + _codecDescVector->push_back(new CodecDescriptor( + get_config_fields_str(AUDIO, CODEC1))); + + _codecDescVector->push_back(new CodecDescriptor( + get_config_fields_str(AUDIO, CODEC2))); + + _codecDescVector->push_back(new CodecDescriptor( + get_config_fields_str(AUDIO, CODEC3))); } void diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index e790c49bb7..6d80f13621 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -145,8 +145,7 @@ SipVoIPLink::initRtpmapCodec (void) // Add payload to rtpmap if it is not already added if (!isInRtpmap(i, payload, _manager->getCodecDescVector())) { snprintf(rtpmap, 127, "%d %s/%d", payload, - _manager->getCodecDescVector()->at(i)->rtpmapPayload(payload).data(), - SAMPLING_RATE); + _manager->getCodecDescVector()->at(i)->rtpmapPayload(payload).data(), SAMPLING_RATE); snprintf(tmp, 63, "%d", payload); eXosip_sdp_negotiation_add_codec( osip_strdup(tmp), NULL, @@ -373,8 +372,9 @@ SipVoIPLink::getEvent (void) char *name; static int countReg = 0; - event = eXosip_event_wait (0, 50); + eXosip_automatic_refresh(); + event = eXosip_event_wait (0, 50); if (event == NULL) { return -1; } -- GitLab