| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library - "Jules' Utility Class Extensions"
 -    Copyright 2004-7 by Raw Material Software ltd.
 - 
 -   ------------------------------------------------------------------------------
 - 
 -    JUCE can be redistributed and/or modified under the terms of the
 -    GNU General Public License, as published by the Free Software Foundation;
 -    either version 2 of the License, or (at your option) any later version.
 - 
 -    JUCE is distributed in the hope that it will be useful,
 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 -    GNU General Public License for more details.
 - 
 -    You should have received a copy of the GNU General Public License
 -    along with JUCE; if not, visit www.gnu.org/licenses or write to the
 -    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 -    Boston, MA 02111-1307 USA
 - 
 -   ------------------------------------------------------------------------------
 - 
 -    If you'd like to release a closed-source product which uses JUCE, commercial
 -    licenses are also available: visit www.rawmaterialsoftware.com/juce for
 -    more information.
 - 
 -   ==============================================================================
 - */
 - 
 - // (This file gets included by juce_win32_NativeCode.cpp, rather than being
 - // compiled on its own).
 - #if JUCE_INCLUDED_FILE
 - 
 - //==============================================================================
 - END_JUCE_NAMESPACE
 - 
 - extern "C"
 - {
 - 
 - // Declare just the minimum number of interfaces for the DSound objects that we need..
 - typedef struct typeDSBUFFERDESC
 - {
 -     DWORD dwSize;
 -     DWORD dwFlags;
 -     DWORD dwBufferBytes;
 -     DWORD dwReserved;
 -     LPWAVEFORMATEX lpwfxFormat;
 -     GUID guid3DAlgorithm;
 - } DSBUFFERDESC;
 - 
 - struct IDirectSoundBuffer;
 - 
 - #undef INTERFACE
 - #define INTERFACE IDirectSound
 - DECLARE_INTERFACE_(IDirectSound, IUnknown)
 - {
 -     STDMETHOD(QueryInterface)       (THIS_ REFIID, LPVOID*) PURE;
 -     STDMETHOD_(ULONG,AddRef)        (THIS) PURE;
 -     STDMETHOD_(ULONG,Release)       (THIS) PURE;
 -     STDMETHOD(CreateSoundBuffer)    (THIS_ DSBUFFERDESC*, IDirectSoundBuffer**, LPUNKNOWN) PURE;
 -     STDMETHOD(GetCaps)              (THIS_ void*) PURE;
 -     STDMETHOD(DuplicateSoundBuffer) (THIS_ IDirectSoundBuffer*, IDirectSoundBuffer**) PURE;
 -     STDMETHOD(SetCooperativeLevel)  (THIS_ HWND, DWORD) PURE;
 -     STDMETHOD(Compact)              (THIS) PURE;
 -     STDMETHOD(GetSpeakerConfig)     (THIS_ LPDWORD) PURE;
 -     STDMETHOD(SetSpeakerConfig)     (THIS_ DWORD) PURE;
 -     STDMETHOD(Initialize)           (THIS_ const GUID*) PURE;
 - };
 - 
 - #undef INTERFACE
 - #define INTERFACE IDirectSoundBuffer
 - DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown)
 - {
 -     STDMETHOD(QueryInterface)       (THIS_ REFIID, LPVOID*) PURE;
 -     STDMETHOD_(ULONG,AddRef)        (THIS) PURE;
 -     STDMETHOD_(ULONG,Release)       (THIS) PURE;
 -     STDMETHOD(GetCaps)              (THIS_ void*) PURE;
 -     STDMETHOD(GetCurrentPosition)   (THIS_ LPDWORD, LPDWORD) PURE;
 -     STDMETHOD(GetFormat)            (THIS_ LPWAVEFORMATEX, DWORD, LPDWORD) PURE;
 -     STDMETHOD(GetVolume)            (THIS_ LPLONG) PURE;
 -     STDMETHOD(GetPan)               (THIS_ LPLONG) PURE;
 -     STDMETHOD(GetFrequency)         (THIS_ LPDWORD) PURE;
 -     STDMETHOD(GetStatus)            (THIS_ LPDWORD) PURE;
 -     STDMETHOD(Initialize)           (THIS_ IDirectSound*, DSBUFFERDESC*) PURE;
 -     STDMETHOD(Lock)                 (THIS_ DWORD, DWORD, LPVOID*, LPDWORD, LPVOID*, LPDWORD, DWORD) PURE;
 -     STDMETHOD(Play)                 (THIS_ DWORD, DWORD, DWORD) PURE;
 -     STDMETHOD(SetCurrentPosition)   (THIS_ DWORD) PURE;
 -     STDMETHOD(SetFormat)            (THIS_ const WAVEFORMATEX*) PURE;
 -     STDMETHOD(SetVolume)            (THIS_ LONG) PURE;
 -     STDMETHOD(SetPan)               (THIS_ LONG) PURE;
 -     STDMETHOD(SetFrequency)         (THIS_ DWORD) PURE;
 -     STDMETHOD(Stop)                 (THIS) PURE;
 -     STDMETHOD(Unlock)               (THIS_ LPVOID, DWORD, LPVOID, DWORD) PURE;
 -     STDMETHOD(Restore)              (THIS) PURE;
 - };
 - 
 - //==============================================================================
 - typedef struct typeDSCBUFFERDESC
 - {
 -     DWORD dwSize;
 -     DWORD dwFlags;
 -     DWORD dwBufferBytes;
 -     DWORD dwReserved;
 -     LPWAVEFORMATEX lpwfxFormat;
 - } DSCBUFFERDESC;
 - 
 - struct IDirectSoundCaptureBuffer;
 - 
 - #undef INTERFACE
 - #define INTERFACE IDirectSoundCapture
 - DECLARE_INTERFACE_(IDirectSoundCapture, IUnknown)
 - {
 -     STDMETHOD(QueryInterface)       (THIS_ REFIID, LPVOID*) PURE;
 -     STDMETHOD_(ULONG,AddRef)        (THIS) PURE;
 -     STDMETHOD_(ULONG,Release)       (THIS) PURE;
 -     STDMETHOD(CreateCaptureBuffer)  (THIS_ DSCBUFFERDESC*, IDirectSoundCaptureBuffer**, LPUNKNOWN) PURE;
 -     STDMETHOD(GetCaps)              (THIS_ void*) PURE;
 -     STDMETHOD(Initialize)           (THIS_ const GUID*) PURE;
 - };
 - 
 - #undef INTERFACE
 - #define INTERFACE IDirectSoundCaptureBuffer
 - DECLARE_INTERFACE_(IDirectSoundCaptureBuffer, IUnknown)
 - {
 -     STDMETHOD(QueryInterface)       (THIS_ REFIID, LPVOID*) PURE;
 -     STDMETHOD_(ULONG,AddRef)        (THIS) PURE;
 -     STDMETHOD_(ULONG,Release)       (THIS) PURE;
 -     STDMETHOD(GetCaps)              (THIS_ void*) PURE;
 -     STDMETHOD(GetCurrentPosition)   (THIS_ LPDWORD, LPDWORD) PURE;
 -     STDMETHOD(GetFormat)            (THIS_ LPWAVEFORMATEX, DWORD, LPDWORD) PURE;
 -     STDMETHOD(GetStatus)            (THIS_ LPDWORD) PURE;
 -     STDMETHOD(Initialize)           (THIS_ IDirectSoundCapture*, DSCBUFFERDESC*) PURE;
 -     STDMETHOD(Lock)                 (THIS_ DWORD, DWORD, LPVOID*, LPDWORD, LPVOID*, LPDWORD, DWORD) PURE;
 -     STDMETHOD(Start)                (THIS_ DWORD) PURE;
 -     STDMETHOD(Stop)                 (THIS) PURE;
 -     STDMETHOD(Unlock)               (THIS_ LPVOID, DWORD, LPVOID, DWORD) PURE;
 - };
 - 
 - };
 - 
 - //==============================================================================
 - BEGIN_JUCE_NAMESPACE
 - 
 - #include "../../../src/juce_appframework/audio/devices/juce_AudioIODeviceType.h"
 - #include "../../../src/juce_appframework/audio/devices/juce_AudioDeviceManager.h"
 - #include "../../../src/juce_appframework/application/juce_Application.h"
 - #include "../../../src/juce_appframework/gui/components/windows/juce_AlertWindow.h"
 - #include "../../../src/juce_core/threads/juce_Thread.h"
 - #include "../../../src/juce_core/basics/juce_Singleton.h"
 - #include "../../../src/juce_core/basics/juce_Time.h"
 - #include "../../../src/juce_core/containers/juce_OwnedArray.h"
 - #include "../../../src/juce_core/text/juce_LocalisedStrings.h"
 - #include "../../../src/juce_appframework/gui/components/buttons/juce_TextButton.h"
 - #include "../../../src/juce_appframework/gui/components/special/juce_AudioDeviceSelectorComponent.h"
 - 
 - 
 - static const String getDSErrorMessage (HRESULT hr)
 - {
 -     const char* result = 0;
 - 
 -     switch (hr)
 -     {
 -     case MAKE_HRESULT(1, 0x878, 10):
 -         result = "Device already allocated";
 -         break;
 -     case MAKE_HRESULT(1, 0x878, 30):
 -         result = "Control unavailable";
 -         break;
 -     case E_INVALIDARG:
 -         result = "Invalid parameter";
 -         break;
 -     case MAKE_HRESULT(1, 0x878, 50):
 -         result = "Invalid call";
 -         break;
 -     case E_FAIL:
 -         result = "Generic error";
 -         break;
 -     case MAKE_HRESULT(1, 0x878, 70):
 -         result = "Priority level error";
 -         break;
 -     case E_OUTOFMEMORY:
 -         result = "Out of memory";
 -         break;
 -     case MAKE_HRESULT(1, 0x878, 100):
 -         result = "Bad format";
 -         break;
 -     case E_NOTIMPL:
 -         result = "Unsupported function";
 -         break;
 -     case MAKE_HRESULT(1, 0x878, 120):
 -         result = "No driver";
 -         break;
 -     case MAKE_HRESULT(1, 0x878, 130):
 -         result = "Already initialised";
 -         break;
 -     case CLASS_E_NOAGGREGATION:
 -         result = "No aggregation";
 -         break;
 -     case MAKE_HRESULT(1, 0x878, 150):
 -         result = "Buffer lost";
 -         break;
 -     case MAKE_HRESULT(1, 0x878, 160):
 -         result = "Another app has priority";
 -         break;
 -     case MAKE_HRESULT(1, 0x878, 170):
 -         result = "Uninitialised";
 -         break;
 -     case E_NOINTERFACE:
 -         result = "No interface";
 -         break;
 -     case S_OK:
 -         result = "No error";
 -         break;
 - 
 -     default:
 -         return "Unknown error: " + String ((int) hr);
 -     }
 - 
 -     return result;
 - }
 - 
 - //==============================================================================
 - #define DS_DEBUGGING 1
 - 
 - #ifdef DS_DEBUGGING
 -     #define CATCH JUCE_CATCH_EXCEPTION
 -     #undef log
 -     #define log(a) Logger::writeToLog(a);
 -     #undef logError
 -     #define logError(a) logDSError(a, __LINE__);
 - 
 -     static void logDSError (HRESULT hr, int lineNum)
 -     {
 -         if (hr != S_OK)
 -         {
 -             String error ("DS error at line ");
 -             error << lineNum << T(" - ") << getDSErrorMessage (hr);
 -             log (error);
 -         }
 -     }
 - #else
 -     #define CATCH JUCE_CATCH_ALL
 -     #define log(a)
 -     #define logError(a)
 - #endif
 - 
 - 
 - //==============================================================================
 - #define DSOUND_FUNCTION(functionName, params) \
 -     typedef HRESULT (WINAPI *type##functionName) params; \
 -     static type##functionName ds##functionName = 0;
 - 
 - #define DSOUND_FUNCTION_LOAD(functionName) \
 -     ds##functionName = (type##functionName) GetProcAddress (h, #functionName);  \
 -     jassert (ds##functionName != 0);
 - 
 - typedef BOOL (CALLBACK *LPDSENUMCALLBACKW) (LPGUID, LPCWSTR, LPCWSTR, LPVOID);
 - typedef BOOL (CALLBACK *LPDSENUMCALLBACKA) (LPGUID, LPCSTR, LPCSTR, LPVOID);
 - 
 - DSOUND_FUNCTION (DirectSoundCreate, (const GUID*, IDirectSound**, LPUNKNOWN))
 - DSOUND_FUNCTION (DirectSoundCaptureCreate, (const GUID*, IDirectSoundCapture**, LPUNKNOWN))
 - DSOUND_FUNCTION (DirectSoundEnumerateW, (LPDSENUMCALLBACKW, LPVOID))
 - DSOUND_FUNCTION (DirectSoundCaptureEnumerateW, (LPDSENUMCALLBACKW, LPVOID))
 - 
 - static void initialiseDSoundFunctions()
 - {
 -     if (dsDirectSoundCreate == 0)
 -     {
 -         HMODULE h = LoadLibraryA ("dsound.dll");
 - 
 -         DSOUND_FUNCTION_LOAD (DirectSoundCreate)
 -         DSOUND_FUNCTION_LOAD (DirectSoundCaptureCreate)
 -         DSOUND_FUNCTION_LOAD (DirectSoundEnumerateW)
 -         DSOUND_FUNCTION_LOAD (DirectSoundCaptureEnumerateW)
 -     }
 - }
 - 
 - //==============================================================================
 - class DSoundInternalOutChannel
 - {
 -     String name;
 -     LPGUID guid;
 -     int sampleRate, bufferSizeSamples;
 -     float* leftBuffer;
 -     float* rightBuffer;
 - 
 -     IDirectSound* pDirectSound;
 -     IDirectSoundBuffer* pOutputBuffer;
 -     DWORD writeOffset;
 -     int totalBytesPerBuffer;
 -     int bytesPerBuffer;
 -     unsigned int lastPlayCursor;
 - 
 - public:
 -     int bitDepth;
 -     bool doneFlag;
 - 
 -     DSoundInternalOutChannel (const String& name_,
 -                               LPGUID guid_,
 -                               int rate,
 -                               int bufferSize,
 -                               float* left,
 -                               float* right)
 -         : name (name_),
 -           guid (guid_),
 -           sampleRate (rate),
 -           bufferSizeSamples (bufferSize),
 -           leftBuffer (left),
 -           rightBuffer (right),
 -           pDirectSound (0),
 -           pOutputBuffer (0),
 -           bitDepth (16)
 -     {
 -     }
 - 
 -     ~DSoundInternalOutChannel()
 -     {
 -         close();
 -     }
 - 
 -     void close()
 -     {
 -         HRESULT hr;
 - 
 -         if (pOutputBuffer != 0)
 -         {
 -             JUCE_TRY
 -             {
 -                 log (T("closing dsound out: ") + name);
 -                 hr = pOutputBuffer->Stop();
 -                 logError (hr);
 -             }
 -             CATCH
 - 
 -             JUCE_TRY
 -             {
 -                 hr = pOutputBuffer->Release();
 -                 logError (hr);
 -             }
 -             CATCH
 - 
 -             pOutputBuffer = 0;
 -         }
 - 
 -         if (pDirectSound != 0)
 -         {
 -             JUCE_TRY
 -             {
 -                 hr = pDirectSound->Release();
 -                 logError (hr);
 -             }
 -             CATCH
 - 
 -             pDirectSound = 0;
 -         }
 -     }
 - 
 -     const String open()
 -     {
 -         log (T("opening dsound out device: ") + name
 -              + T("  rate=") + String (sampleRate)
 -              + T(" bits=") + String (bitDepth)
 -              + T(" buf=") + String (bufferSizeSamples));
 - 
 -         pDirectSound = 0;
 -         pOutputBuffer = 0;
 -         writeOffset = 0;
 - 
 -         String error;
 -         HRESULT hr = E_NOINTERFACE;
 - 
 -         if (dsDirectSoundCreate != 0)
 -             hr = dsDirectSoundCreate (guid, &pDirectSound, 0);
 - 
 -         if (hr == S_OK)
 -         {
 -             bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15;
 -             totalBytesPerBuffer = (3 * bytesPerBuffer) & ~15;
 -             const int numChannels = 2;
 - 
 -             hr = pDirectSound->SetCooperativeLevel (GetDesktopWindow(), 2 /* DSSCL_PRIORITY  */);
 -             logError (hr);
 - 
 -             if (hr == S_OK)
 -             {
 -                 IDirectSoundBuffer* pPrimaryBuffer;
 - 
 -                 DSBUFFERDESC primaryDesc;
 -                 zerostruct (primaryDesc);
 - 
 -                 primaryDesc.dwSize = sizeof (DSBUFFERDESC);
 -                 primaryDesc.dwFlags = 1 /* DSBCAPS_PRIMARYBUFFER */;
 -                 primaryDesc.dwBufferBytes = 0;
 -                 primaryDesc.lpwfxFormat = 0;
 - 
 -                 log ("opening dsound out step 2");
 -                 hr = pDirectSound->CreateSoundBuffer (&primaryDesc, &pPrimaryBuffer, 0);
 -                 logError (hr);
 - 
 -                 if (hr == S_OK)
 -                 {
 -                     WAVEFORMATEX wfFormat;
 -                     wfFormat.wFormatTag = WAVE_FORMAT_PCM;
 -                     wfFormat.nChannels = (unsigned short) numChannels;
 -                     wfFormat.nSamplesPerSec = sampleRate;
 -                     wfFormat.wBitsPerSample = (unsigned short) bitDepth;
 -                     wfFormat.nBlockAlign = (unsigned short) (wfFormat.nChannels * wfFormat.wBitsPerSample / 8);
 -                     wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
 -                     wfFormat.cbSize = 0;
 - 
 -                     hr = pPrimaryBuffer->SetFormat (&wfFormat);
 -                     logError (hr);
 - 
 -                     if (hr == S_OK)
 -                     {
 -                         DSBUFFERDESC secondaryDesc;
 -                         zerostruct (secondaryDesc);
 - 
 -                         secondaryDesc.dwSize = sizeof (DSBUFFERDESC);
 -                         secondaryDesc.dwFlags =  0x8000 /* DSBCAPS_GLOBALFOCUS */
 -                                                   | 0x10000 /* DSBCAPS_GETCURRENTPOSITION2 */;
 -                         secondaryDesc.dwBufferBytes = totalBytesPerBuffer;
 -                         secondaryDesc.lpwfxFormat = &wfFormat;
 - 
 -                         hr = pDirectSound->CreateSoundBuffer (&secondaryDesc, &pOutputBuffer, 0);
 -                         logError (hr);
 - 
 -                         if (hr == S_OK)
 -                         {
 -                             log ("opening dsound out step 3");
 - 
 -                             DWORD dwDataLen;
 -                             unsigned char* pDSBuffData;
 - 
 -                             hr = pOutputBuffer->Lock (0, totalBytesPerBuffer,
 -                                                       (LPVOID*) &pDSBuffData, &dwDataLen, 0, 0, 0);
 -                             logError (hr);
 - 
 -                             if (hr == S_OK)
 -                             {
 -                                 zeromem (pDSBuffData, dwDataLen);
 - 
 -                                 hr = pOutputBuffer->Unlock (pDSBuffData, dwDataLen, 0, 0);
 - 
 -                                 if (hr == S_OK)
 -                                 {
 -                                     hr = pOutputBuffer->SetCurrentPosition (0);
 - 
 -                                     if (hr == S_OK)
 -                                     {
 -                                         hr = pOutputBuffer->Play (0, 0, 1 /* DSBPLAY_LOOPING */);
 - 
 -                                         if (hr == S_OK)
 -                                             return String::empty;
 -                                     }
 -                                 }
 -                             }
 -                         }
 -                     }
 -                 }
 -             }
 -         }
 - 
 -         error = getDSErrorMessage (hr);
 -         close();
 -         return error;
 -     }
 - 
 -     void synchronisePosition()
 -     {
 -         if (pOutputBuffer != 0)
 -         {
 -             DWORD playCursor;
 -             pOutputBuffer->GetCurrentPosition (&playCursor, &writeOffset);
 -         }
 -     }
 - 
 -     bool service()
 -     {
 -         if (pOutputBuffer == 0)
 -             return true;
 - 
 -         DWORD playCursor, writeCursor;
 -         HRESULT hr = pOutputBuffer->GetCurrentPosition (&playCursor, &writeCursor);
 - 
 -         if (hr != S_OK)
 -         {
 -             logError (hr);
 -             jassertfalse
 -             return true;
 -         }
 - 
 -         int playWriteGap = writeCursor - playCursor;
 -         if (playWriteGap < 0)
 -             playWriteGap += totalBytesPerBuffer;
 - 
 -         int bytesEmpty = playCursor - writeOffset;
 - 
 -         if (bytesEmpty < 0)
 -             bytesEmpty += totalBytesPerBuffer;
 - 
 -         if (bytesEmpty > (totalBytesPerBuffer - playWriteGap))
 -         {
 -             writeOffset = writeCursor;
 -             bytesEmpty = totalBytesPerBuffer - playWriteGap;
 -         }
 - 
 -         if (bytesEmpty >= bytesPerBuffer)
 -         {
 -             LPBYTE lpbuf1 = 0;
 -             LPBYTE lpbuf2 = 0;
 -             DWORD dwSize1 = 0;
 -             DWORD dwSize2 = 0;
 - 
 -             HRESULT hr = pOutputBuffer->Lock (writeOffset,
 -                                               bytesPerBuffer,
 -                                               (void**) &lpbuf1, &dwSize1,
 -                                               (void**) &lpbuf2, &dwSize2, 0);
 - 
 -             if (hr == MAKE_HRESULT (1, 0x878, 150)) // DSERR_BUFFERLOST
 -             {
 -                 pOutputBuffer->Restore();
 - 
 -                 hr = pOutputBuffer->Lock (writeOffset,
 -                                           bytesPerBuffer,
 -                                           (void**) &lpbuf1, &dwSize1,
 -                                           (void**) &lpbuf2, &dwSize2, 0);
 -             }
 - 
 -             if (hr == S_OK)
 -             {
 -                 if (bitDepth == 16)
 -                 {
 -                     const float gainL = 32767.0f;
 -                     const float gainR = 32767.0f;
 - 
 -                     int* dest = (int*)lpbuf1;
 -                     const float* left = leftBuffer;
 -                     const float* right = rightBuffer;
 -                     int samples1 = dwSize1 >> 2;
 -                     int samples2 = dwSize2 >> 2;
 - 
 -                     if (left == 0)
 -                     {
 -                         while (--samples1 >= 0)
 -                         {
 -                             int r = roundFloatToInt (gainR * *right++);
 - 
 -                             if (r < -32768)
 -                                 r = -32768;
 -                             else if (r > 32767)
 -                                 r = 32767;
 - 
 -                             *dest++ = (r << 16);
 -                         }
 - 
 -                         dest = (int*)lpbuf2;
 - 
 -                         while (--samples2 >= 0)
 -                         {
 -                             int r = roundFloatToInt (gainR * *right++);
 - 
 -                             if (r < -32768)
 -                                 r = -32768;
 -                             else if (r > 32767)
 -                                 r = 32767;
 - 
 -                             *dest++ = (r << 16);
 -                         }
 -                     }
 -                     else if (right == 0)
 -                     {
 -                         while (--samples1 >= 0)
 -                         {
 -                             int l = roundFloatToInt (gainL * *left++);
 - 
 -                             if (l < -32768)
 -                                 l = -32768;
 -                             else if (l > 32767)
 -                                 l = 32767;
 - 
 -                             l &= 0xffff;
 - 
 -                             *dest++ = l;
 -                         }
 - 
 -                         dest = (int*)lpbuf2;
 - 
 -                         while (--samples2 >= 0)
 -                         {
 -                             int l = roundFloatToInt (gainL * *left++);
 - 
 -                             if (l < -32768)
 -                                 l = -32768;
 -                             else if (l > 32767)
 -                                 l = 32767;
 - 
 -                             l &= 0xffff;
 - 
 -                             *dest++ = l;
 -                         }
 -                     }
 -                     else
 -                     {
 -                         while (--samples1 >= 0)
 -                         {
 -                             int l = roundFloatToInt (gainL * *left++);
 - 
 -                             if (l < -32768)
 -                                 l = -32768;
 -                             else if (l > 32767)
 -                                 l = 32767;
 - 
 -                             l &= 0xffff;
 - 
 -                             int r = roundFloatToInt (gainR * *right++);
 - 
 -                             if (r < -32768)
 -                                 r = -32768;
 -                             else if (r > 32767)
 -                                 r = 32767;
 - 
 -                             *dest++ = (r << 16) | l;
 -                         }
 - 
 -                         dest = (int*)lpbuf2;
 - 
 -                         while (--samples2 >= 0)
 -                         {
 -                             int l = roundFloatToInt (gainL * *left++);
 - 
 -                             if (l < -32768)
 -                                 l = -32768;
 -                             else if (l > 32767)
 -                                 l = 32767;
 - 
 -                             l &= 0xffff;
 - 
 -                             int r = roundFloatToInt (gainR * *right++);
 - 
 -                             if (r < -32768)
 -                                 r = -32768;
 -                             else if (r > 32767)
 -                                 r = 32767;
 - 
 -                             *dest++ = (r << 16) | l;
 -                         }
 -                     }
 -                 }
 -                 else
 -                 {
 -                     jassertfalse
 -                 }
 - 
 -                 writeOffset = (writeOffset + dwSize1 + dwSize2) % totalBytesPerBuffer;
 - 
 -                 pOutputBuffer->Unlock (lpbuf1, dwSize1, lpbuf2, dwSize2);
 -             }
 -             else
 -             {
 -                 jassertfalse
 -                 logError (hr);
 -             }
 - 
 -             bytesEmpty -= bytesPerBuffer;
 - 
 -             return true;
 -         }
 -         else
 -         {
 -             return false;
 -         }
 -     }
 - };
 - 
 - //==============================================================================
 - struct DSoundInternalInChannel
 - {
 -     String name;
 -     LPGUID guid;
 -     int sampleRate, bufferSizeSamples;
 -     float* leftBuffer;
 -     float* rightBuffer;
 - 
 -     IDirectSound* pDirectSound;
 -     IDirectSoundCapture* pDirectSoundCapture;
 -     IDirectSoundCaptureBuffer* pInputBuffer;
 - 
 - public:
 -     unsigned int readOffset;
 -     int bytesPerBuffer, totalBytesPerBuffer;
 -     int bitDepth;
 -     bool doneFlag;
 - 
 -     DSoundInternalInChannel (const String& name_,
 -                              LPGUID guid_,
 -                              int rate,
 -                              int bufferSize,
 -                              float* left,
 -                              float* right)
 -         : name (name_),
 -           guid (guid_),
 -           sampleRate (rate),
 -           bufferSizeSamples (bufferSize),
 -           leftBuffer (left),
 -           rightBuffer (right),
 -           pDirectSound (0),
 -           pDirectSoundCapture (0),
 -           pInputBuffer (0),
 -           bitDepth (16)
 -     {
 -     }
 - 
 -     ~DSoundInternalInChannel()
 -     {
 -         close();
 -     }
 - 
 -     void close()
 -     {
 -         HRESULT hr;
 - 
 -         if (pInputBuffer != 0)
 -         {
 -             JUCE_TRY
 -             {
 -                 log (T("closing dsound in: ") + name);
 -                 hr = pInputBuffer->Stop();
 -                 logError (hr);
 -             }
 -             CATCH
 - 
 -             JUCE_TRY
 -             {
 -                 hr = pInputBuffer->Release();
 -                 logError (hr);
 -             }
 -             CATCH
 - 
 -             pInputBuffer = 0;
 -         }
 - 
 -         if (pDirectSoundCapture != 0)
 -         {
 -             JUCE_TRY
 -             {
 -                 hr = pDirectSoundCapture->Release();
 -                 logError (hr);
 -             }
 -             CATCH
 - 
 -             pDirectSoundCapture = 0;
 -         }
 - 
 -         if (pDirectSound != 0)
 -         {
 -             JUCE_TRY
 -             {
 -                 hr = pDirectSound->Release();
 -                 logError (hr);
 -             }
 -             CATCH
 - 
 -             pDirectSound = 0;
 -         }
 -     }
 - 
 -     const String open()
 -     {
 -         log (T("opening dsound in device: ") + name
 -              + T("  rate=") + String (sampleRate) + T(" bits=") + String (bitDepth) + T(" buf=") + String (bufferSizeSamples));
 - 
 -         pDirectSound = 0;
 -         pDirectSoundCapture = 0;
 -         pInputBuffer = 0;
 -         readOffset = 0;
 -         totalBytesPerBuffer = 0;
 - 
 -         String error;
 -         HRESULT hr = E_NOINTERFACE;
 - 
 -         if (dsDirectSoundCaptureCreate != 0)
 -             hr = dsDirectSoundCaptureCreate (guid, &pDirectSoundCapture, 0);
 - 
 -         logError (hr);
 - 
 -         if (hr == S_OK)
 -         {
 -             const int numChannels = 2;
 -             bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15;
 -             totalBytesPerBuffer = (3 * bytesPerBuffer) & ~15;
 - 
 -             WAVEFORMATEX wfFormat;
 -             wfFormat.wFormatTag = WAVE_FORMAT_PCM;
 -             wfFormat.nChannels = (unsigned short)numChannels;
 -             wfFormat.nSamplesPerSec = sampleRate;
 -             wfFormat.wBitsPerSample = (unsigned short)bitDepth;
 -             wfFormat.nBlockAlign = (unsigned short)(wfFormat.nChannels * (wfFormat.wBitsPerSample / 8));
 -             wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
 -             wfFormat.cbSize = 0;
 - 
 -             DSCBUFFERDESC captureDesc;
 -             zerostruct (captureDesc);
 - 
 -             captureDesc.dwSize = sizeof (DSCBUFFERDESC);
 -             captureDesc.dwFlags = 0;
 -             captureDesc.dwBufferBytes = totalBytesPerBuffer;
 -             captureDesc.lpwfxFormat = &wfFormat;
 - 
 -             log (T("opening dsound in step 2"));
 -             hr = pDirectSoundCapture->CreateCaptureBuffer (&captureDesc, &pInputBuffer, 0);
 - 
 -             logError (hr);
 - 
 -             if (hr == S_OK)
 -             {
 -                 hr = pInputBuffer->Start (1 /* DSCBSTART_LOOPING */);
 -                 logError (hr);
 - 
 -                 if (hr == S_OK)
 -                     return String::empty;
 -             }
 -         }
 - 
 -         error = getDSErrorMessage (hr);
 -         close();
 - 
 -         return error;
 -     }
 - 
 -     void synchronisePosition()
 -     {
 -         if (pInputBuffer != 0)
 -         {
 -             DWORD capturePos;
 -             pInputBuffer->GetCurrentPosition (&capturePos, (DWORD*)&readOffset);
 -         }
 -     }
 - 
 -     bool service()
 -     {
 -         if (pInputBuffer == 0)
 -             return true;
 - 
 -         DWORD capturePos, readPos;
 -         HRESULT hr = pInputBuffer->GetCurrentPosition (&capturePos, &readPos);
 -         logError (hr);
 - 
 -         if (hr != S_OK)
 -             return true;
 - 
 -         int bytesFilled = readPos - readOffset;
 -         if (bytesFilled < 0)
 -             bytesFilled += totalBytesPerBuffer;
 - 
 -         if (bytesFilled >= bytesPerBuffer)
 -         {
 -             LPBYTE lpbuf1 = 0;
 -             LPBYTE lpbuf2 = 0;
 -             DWORD dwsize1 = 0;
 -             DWORD dwsize2 = 0;
 - 
 -             HRESULT hr = pInputBuffer->Lock (readOffset,
 -                                              bytesPerBuffer,
 -                                              (void**) &lpbuf1, &dwsize1,
 -                                              (void**) &lpbuf2, &dwsize2, 0);
 - 
 -             if (hr == S_OK)
 -             {
 -                 if (bitDepth == 16)
 -                 {
 -                     const float g = 1.0f / 32768.0f;
 - 
 -                     float* destL = leftBuffer;
 -                     float* destR = rightBuffer;
 -                     int samples1 = dwsize1 >> 2;
 -                     int samples2 = dwsize2 >> 2;
 - 
 -                     const short* src = (const short*)lpbuf1;
 - 
 -                     if (destL == 0)
 -                     {
 -                         while (--samples1 >= 0)
 -                         {
 -                             ++src;
 -                             *destR++ = *src++ * g;
 -                         }
 - 
 -                         src = (const short*)lpbuf2;
 - 
 -                         while (--samples2 >= 0)
 -                         {
 -                             ++src;
 -                             *destR++ = *src++ * g;
 -                         }
 -                     }
 -                     else if (destR == 0)
 -                     {
 -                         while (--samples1 >= 0)
 -                         {
 -                             *destL++ = *src++ * g;
 -                             ++src;
 -                         }
 - 
 -                         src = (const short*)lpbuf2;
 - 
 -                         while (--samples2 >= 0)
 -                         {
 -                             *destL++ = *src++ * g;
 -                             ++src;
 -                         }
 -                     }
 -                     else
 -                     {
 -                         while (--samples1 >= 0)
 -                         {
 -                             *destL++ = *src++ * g;
 -                             *destR++ = *src++ * g;
 -                         }
 - 
 -                         src = (const short*)lpbuf2;
 - 
 -                         while (--samples2 >= 0)
 -                         {
 -                             *destL++ = *src++ * g;
 -                             *destR++ = *src++ * g;
 -                         }
 -                     }
 -                 }
 -                 else
 -                 {
 -                     jassertfalse
 -                 }
 - 
 -                 readOffset = (readOffset + dwsize1 + dwsize2) % totalBytesPerBuffer;
 - 
 -                 pInputBuffer->Unlock (lpbuf1, dwsize1, lpbuf2, dwsize2);
 -             }
 -             else
 -             {
 -                 logError (hr);
 -                 jassertfalse
 -             }
 - 
 -             bytesFilled -= bytesPerBuffer;
 - 
 -             return true;
 -         }
 -         else
 -         {
 -             return false;
 -         }
 -     }
 - };
 - 
 - //==============================================================================
 - class DSoundAudioIODevice  : public AudioIODevice,
 -                              public Thread
 - {
 - public:
 -     DSoundAudioIODevice (const String& deviceName,
 -                          const int outputDeviceIndex_,
 -                          const int inputDeviceIndex_)
 -         : AudioIODevice (deviceName, "DirectSound"),
 -           Thread ("Juce DSound"),
 -           isOpen_ (false),
 -           isStarted (false),
 -           outputDeviceIndex (outputDeviceIndex_),
 -           inputDeviceIndex (inputDeviceIndex_),
 -           inChans (4),
 -           outChans (4),
 -           numInputBuffers (0),
 -           numOutputBuffers (0),
 -           totalSamplesOut (0),
 -           sampleRate (0.0),
 -           inputBuffers (0),
 -           outputBuffers (0),
 -           callback (0),
 -           bufferSizeSamples (0)
 -     {
 -         if (outputDeviceIndex_ >= 0)
 -         {
 -             outChannels.add (TRANS("Left"));
 -             outChannels.add (TRANS("Right"));
 -         }
 - 
 -         if (inputDeviceIndex_ >= 0)
 -         {
 -             inChannels.add (TRANS("Left"));
 -             inChannels.add (TRANS("Right"));
 -         }
 -     }
 - 
 -     ~DSoundAudioIODevice()
 -     {
 -         close();
 -     }
 - 
 -     const StringArray getOutputChannelNames()
 -     {
 -         return outChannels;
 -     }
 - 
 -     const StringArray getInputChannelNames()
 -     {
 -         return inChannels;
 -     }
 - 
 -     int getNumSampleRates()
 -     {
 -         return 4;
 -     }
 - 
 -     double getSampleRate (int index)
 -     {
 -         const double samps[] = { 44100.0, 48000.0, 88200.0, 96000.0 };
 - 
 -         return samps [jlimit (0, 3, index)];
 -     }
 - 
 -     int getNumBufferSizesAvailable()
 -     {
 -         return 50;
 -     }
 - 
 -     int getBufferSizeSamples (int index)
 -     {
 -         int n = 64;
 -         for (int i = 0; i < index; ++i)
 -             n += (n < 512) ? 32
 -                            : ((n < 1024) ? 64
 -                                          : ((n < 2048) ? 128 : 256));
 - 
 -         return n;
 -     }
 - 
 -     int getDefaultBufferSize()
 -     {
 -         return 2560;
 -     }
 - 
 -     const String open (const BitArray& inputChannels,
 -                        const BitArray& outputChannels,
 -                        double sampleRate,
 -                        int bufferSizeSamples)
 -     {
 -         lastError = openDevice (inputChannels, outputChannels, sampleRate, bufferSizeSamples);
 -         isOpen_ = lastError.isEmpty();
 - 
 -         return lastError;
 -     }
 - 
 -     void close()
 -     {
 -         stop();
 - 
 -         if (isOpen_)
 -         {
 -             closeDevice();
 -             isOpen_ = false;
 -         }
 -     }
 - 
 -     bool isOpen()
 -     {
 -         return isOpen_ && isThreadRunning();
 -     }
 - 
 -     int getCurrentBufferSizeSamples()
 -     {
 -         return bufferSizeSamples;
 -     }
 - 
 -     double getCurrentSampleRate()
 -     {
 -         return sampleRate;
 -     }
 - 
 -     int getCurrentBitDepth()
 -     {
 -         int i, bits = 256;
 - 
 -         for (i = inChans.size(); --i >= 0;)
 -             bits = jmin (bits, inChans[i]->bitDepth);
 - 
 -         for (i = outChans.size(); --i >= 0;)
 -             bits = jmin (bits, outChans[i]->bitDepth);
 - 
 -         if (bits > 32)
 -             bits = 16;
 - 
 -         return bits;
 -     }
 - 
 -     const BitArray getActiveOutputChannels() const
 -     {
 -         return enabledOutputs;
 -     }
 - 
 -     const BitArray getActiveInputChannels() const
 -     {
 -         return enabledInputs;
 -     }
 - 
 -     int getOutputLatencyInSamples()
 -     {
 -         return (int) (getCurrentBufferSizeSamples() * 1.5);
 -     }
 - 
 -     int getInputLatencyInSamples()
 -     {
 -         return getOutputLatencyInSamples();
 -     }
 - 
 -     void start (AudioIODeviceCallback* call)
 -     {
 -         if (isOpen_ && call != 0 && ! isStarted)
 -         {
 -             if (! isThreadRunning())
 -             {
 -                 // something gone wrong and the thread's stopped..
 -                 isOpen_ = false;
 -                 return;
 -             }
 - 
 -             call->audioDeviceAboutToStart (this);
 - 
 -             const ScopedLock sl (startStopLock);
 -             callback = call;
 -             isStarted = true;
 -         }
 -     }
 - 
 -     void stop()
 -     {
 -         if (isStarted)
 -         {
 -             AudioIODeviceCallback* const callbackLocal = callback;
 - 
 -             {
 -                 const ScopedLock sl (startStopLock);
 -                 isStarted = false;
 -             }
 - 
 -             if (callbackLocal != 0)
 -                 callbackLocal->audioDeviceStopped();
 -         }
 -     }
 - 
 -     bool isPlaying()
 -     {
 -         return isStarted && isOpen_ && isThreadRunning();
 -     }
 - 
 -     const String getLastError()
 -     {
 -         return lastError;
 -     }
 - 
 -     //==============================================================================
 -     juce_UseDebuggingNewOperator
 - 
 -     StringArray inChannels, outChannels;
 -     int outputDeviceIndex, inputDeviceIndex;
 - 
 - private:
 -     bool isOpen_;
 -     bool isStarted;
 -     String lastError;
 - 
 -     OwnedArray <DSoundInternalInChannel> inChans;
 -     OwnedArray <DSoundInternalOutChannel> outChans;
 -     WaitableEvent startEvent;
 - 
 -     int numInputBuffers, numOutputBuffers, bufferSizeSamples;
 -     int volatile totalSamplesOut;
 -     int64 volatile lastBlockTime;
 -     double sampleRate;
 -     BitArray enabledInputs, enabledOutputs;
 -     float** inputBuffers;
 -     float** outputBuffers;
 - 
 -     AudioIODeviceCallback* callback;
 -     CriticalSection startStopLock;
 - 
 -     DSoundAudioIODevice (const DSoundAudioIODevice&);
 -     const DSoundAudioIODevice& operator= (const DSoundAudioIODevice&);
 - 
 -     const String openDevice (const BitArray& inputChannels,
 -                              const BitArray& outputChannels,
 -                              double sampleRate_,
 -                              int bufferSizeSamples_);
 - 
 -     void closeDevice()
 -     {
 -         isStarted = false;
 -         stopThread (5000);
 - 
 -         inChans.clear();
 -         outChans.clear();
 - 
 -         int i;
 -         for (i = 0; i < numInputBuffers; ++i)
 -             juce_free (inputBuffers[i]);
 - 
 -         delete[] inputBuffers;
 -         inputBuffers = 0;
 -         numInputBuffers = 0;
 - 
 -         for (i = 0; i < numOutputBuffers; ++i)
 -             juce_free (outputBuffers[i]);
 - 
 -         delete[] outputBuffers;
 -         outputBuffers = 0;
 -         numOutputBuffers = 0;
 -     }
 - 
 -     void resync()
 -     {
 -         if (! threadShouldExit())
 -         {
 -             sleep (5);
 - 
 -             int i;
 -             for (i = 0; i < outChans.size(); ++i)
 -                 outChans.getUnchecked(i)->synchronisePosition();
 - 
 -             for (i = 0; i < inChans.size(); ++i)
 -                 inChans.getUnchecked(i)->synchronisePosition();
 -         }
 -     }
 - 
 - public:
 -     void run()
 -     {
 -         while (! threadShouldExit())
 -         {
 -             if (wait (100))
 -                 break;
 -         }
 - 
 -         const int latencyMs = (int) (bufferSizeSamples * 1000.0 / sampleRate);
 -         const int maxTimeMS = jmax (5, 3 * latencyMs);
 - 
 -         while (! threadShouldExit())
 -         {
 -             int numToDo = 0;
 -             uint32 startTime = Time::getMillisecondCounter();
 - 
 -             int i;
 -             for (i = inChans.size(); --i >= 0;)
 -             {
 -                 inChans.getUnchecked(i)->doneFlag = false;
 -                 ++numToDo;
 -             }
 - 
 -             for (i = outChans.size(); --i >= 0;)
 -             {
 -                 outChans.getUnchecked(i)->doneFlag = false;
 -                 ++numToDo;
 -             }
 - 
 -             if (numToDo > 0)
 -             {
 -                 const int maxCount = 3;
 -                 int count = maxCount;
 - 
 -                 for (;;)
 -                 {
 -                     for (i = inChans.size(); --i >= 0;)
 -                     {
 -                         DSoundInternalInChannel* const in = inChans.getUnchecked(i);
 - 
 -                         if ((! in->doneFlag) && in->service())
 -                         {
 -                             in->doneFlag = true;
 -                             --numToDo;
 -                         }
 -                     }
 - 
 -                     for (i = outChans.size(); --i >= 0;)
 -                     {
 -                         DSoundInternalOutChannel* const out = outChans.getUnchecked(i);
 - 
 -                         if ((! out->doneFlag) && out->service())
 -                         {
 -                             out->doneFlag = true;
 -                             --numToDo;
 -                         }
 -                     }
 - 
 -                     if (numToDo <= 0)
 -                         break;
 - 
 -                     if (Time::getMillisecondCounter() > startTime + maxTimeMS)
 -                     {
 -                         resync();
 -                         break;
 -                     }
 - 
 -                     if (--count <= 0)
 -                     {
 -                         Sleep (1);
 -                         count = maxCount;
 -                     }
 - 
 -                     if (threadShouldExit())
 -                         return;
 -                 }
 -             }
 -             else
 -             {
 -                 sleep (1);
 -             }
 - 
 -             const ScopedLock sl (startStopLock);
 - 
 -             if (isStarted)
 -             {
 -                 JUCE_TRY
 -                 {
 -                     callback->audioDeviceIOCallback ((const float**) inputBuffers,
 -                                                      numInputBuffers,
 -                                                      outputBuffers,
 -                                                      numOutputBuffers,
 -                                                      bufferSizeSamples);
 -                 }
 -                 JUCE_CATCH_EXCEPTION
 - 
 -                 totalSamplesOut += bufferSizeSamples;
 -             }
 -             else
 -             {
 -                 for (i = 0; i < numOutputBuffers; ++i)
 -                     if (outputBuffers[i] != 0)
 -                         zeromem (outputBuffers[i], bufferSizeSamples * sizeof (float));
 - 
 -                 totalSamplesOut = 0;
 -                 sleep (1);
 -             }
 -         }
 -     }
 - };
 - 
 - 
 - //==============================================================================
 - class DSoundAudioIODeviceType  : public AudioIODeviceType
 - {
 - public:
 -     DSoundAudioIODeviceType()
 -         : AudioIODeviceType (T("DirectSound")),
 -           hasScanned (false)
 -     {
 -         initialiseDSoundFunctions();
 -     }
 - 
 -     ~DSoundAudioIODeviceType()
 -     {
 -     }
 - 
 -     //==============================================================================
 -     void scanForDevices()
 -     {
 -         hasScanned = true;
 - 
 -         outputDeviceNames.clear();
 -         outputGuids.clear();
 -         inputDeviceNames.clear();
 -         inputGuids.clear();
 - 
 -         if (dsDirectSoundEnumerateW != 0)
 -         {
 -             dsDirectSoundEnumerateW (outputEnumProcW, this);
 -             dsDirectSoundCaptureEnumerateW (inputEnumProcW, this);
 -         }
 -     }
 - 
 -     const StringArray getDeviceNames (const bool wantInputNames) const
 -     {
 -         jassert (hasScanned); // need to call scanForDevices() before doing this
 - 
 -         return wantInputNames ? inputDeviceNames
 -                                : outputDeviceNames;
 -     }
 - 
 -     int getDefaultDeviceIndex (const bool /*forInput*/) const
 -     {
 -         jassert (hasScanned); // need to call scanForDevices() before doing this
 -         return 0;
 -     }
 - 
 -     int getIndexOfDevice (AudioIODevice* device, const bool asInput) const
 -     {
 -         jassert (hasScanned); // need to call scanForDevices() before doing this
 - 
 -         DSoundAudioIODevice* const d = dynamic_cast <DSoundAudioIODevice*> (device);
 -         if (d == 0)
 -             return -1;
 - 
 -         return asInput ? d->inputDeviceIndex
 -                        : d->outputDeviceIndex;
 -     }
 - 
 -     bool hasSeparateInputsAndOutputs() const    { return true; }
 - 
 -     AudioIODevice* createDevice (const String& outputDeviceName,
 -                                  const String& inputDeviceName)
 -     {
 -         jassert (hasScanned); // need to call scanForDevices() before doing this
 - 
 -         const int outputIndex = outputDeviceNames.indexOf (outputDeviceName);
 -         const int inputIndex = inputDeviceNames.indexOf (inputDeviceName);
 - 
 -         if (outputIndex >= 0 || inputIndex >= 0)
 -             return new DSoundAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName
 -                                                                           : inputDeviceName,
 -                                             outputIndex, inputIndex);
 - 
 -         return 0;
 -     }
 - 
 -     //==============================================================================
 -     juce_UseDebuggingNewOperator
 - 
 -     StringArray outputDeviceNames;
 -     OwnedArray <GUID> outputGuids;
 - 
 -     StringArray inputDeviceNames;
 -     OwnedArray <GUID> inputGuids;
 - 
 - private:
 -     bool hasScanned;
 - 
 -     //==============================================================================
 -     BOOL outputEnumProc (LPGUID lpGUID, String desc)
 -     {
 -         desc = desc.trim();
 - 
 -         if (desc.isNotEmpty())
 -         {
 -             const String origDesc (desc);
 - 
 -             int n = 2;
 -             while (outputDeviceNames.contains (desc))
 -                 desc = origDesc + T(" (") + String (n++) + T(")");
 - 
 -             outputDeviceNames.add (desc);
 - 
 -             if (lpGUID != 0)
 -                 outputGuids.add (new GUID (*lpGUID));
 -             else
 -                 outputGuids.add (0);
 -         }
 - 
 -         return TRUE;
 -     }
 - 
 -     static BOOL CALLBACK outputEnumProcW (LPGUID lpGUID, LPCWSTR description, LPCWSTR, LPVOID object)
 -     {
 -         return ((DSoundAudioIODeviceType*) object)
 -                     ->outputEnumProc (lpGUID, String (description));
 -     }
 - 
 -     static BOOL CALLBACK outputEnumProcA (LPGUID lpGUID, LPCTSTR description, LPCTSTR, LPVOID object)
 -     {
 -         return ((DSoundAudioIODeviceType*) object)
 -                     ->outputEnumProc (lpGUID, String (description));
 -     }
 - 
 -     //==============================================================================
 -     BOOL CALLBACK inputEnumProc (LPGUID lpGUID, String desc)
 -     {
 -         desc = desc.trim();
 - 
 -         if (desc.isNotEmpty())
 -         {
 -             const String origDesc (desc);
 - 
 -             int n = 2;
 -             while (inputDeviceNames.contains (desc))
 -                 desc = origDesc + T(" (") + String (n++) + T(")");
 - 
 -             inputDeviceNames.add (desc);
 - 
 -             if (lpGUID != 0)
 -                 inputGuids.add (new GUID (*lpGUID));
 -             else
 -                 inputGuids.add (0);
 -         }
 - 
 -         return TRUE;
 -     }
 - 
 -     static BOOL CALLBACK inputEnumProcW (LPGUID lpGUID, LPCWSTR description, LPCWSTR, LPVOID object)
 -     {
 -         return ((DSoundAudioIODeviceType*) object)
 -                     ->inputEnumProc (lpGUID, String (description));
 -     }
 - 
 -     static BOOL CALLBACK inputEnumProcA (LPGUID lpGUID, LPCTSTR description, LPCTSTR, LPVOID object)
 -     {
 -         return ((DSoundAudioIODeviceType*) object)
 -                     ->inputEnumProc (lpGUID, String (description));
 -     }
 - 
 -     //==============================================================================
 -     DSoundAudioIODeviceType (const DSoundAudioIODeviceType&);
 -     const DSoundAudioIODeviceType& operator= (const DSoundAudioIODeviceType&);
 - };
 - 
 - //==============================================================================
 - AudioIODeviceType* juce_createDefaultAudioIODeviceType()
 - {
 -     return new DSoundAudioIODeviceType();
 - }
 - 
 - //==============================================================================
 - const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels,
 -                                               const BitArray& outputChannels,
 -                                               double sampleRate_,
 -                                               int bufferSizeSamples_)
 - {
 -     closeDevice();
 -     totalSamplesOut = 0;
 - 
 -     sampleRate = sampleRate_;
 - 
 -     if (bufferSizeSamples_ <= 0)
 -         bufferSizeSamples_ = 960; // use as a default size if none is set.
 - 
 -     bufferSizeSamples = bufferSizeSamples_ & ~7;
 - 
 -     DSoundAudioIODeviceType dlh;
 -     dlh.scanForDevices();
 - 
 -     enabledInputs = inputChannels;
 -     enabledInputs.setRange (inChannels.size(),
 -                             enabledInputs.getHighestBit() + 1 - inChannels.size(),
 -                             false);
 - 
 -     numInputBuffers = enabledInputs.countNumberOfSetBits();
 -     inputBuffers = new float* [numInputBuffers + 2];
 -     zeromem (inputBuffers, sizeof (float*) * numInputBuffers + 2);
 -     int i, numIns = 0;
 - 
 -     for (i = 0; i <= enabledInputs.getHighestBit(); i += 2)
 -     {
 -         float* left = 0;
 -         float* right = 0;
 - 
 -         if (enabledInputs[i])
 -             left = inputBuffers[numIns++] = (float*) juce_calloc ((bufferSizeSamples + 16) * sizeof (float));
 - 
 -         if (enabledInputs[i + 1])
 -             right = inputBuffers[numIns++] = (float*) juce_calloc ((bufferSizeSamples + 16) * sizeof (float));
 - 
 -         if (left != 0 || right != 0)
 -             inChans.add (new DSoundInternalInChannel (dlh.inputDeviceNames [inputDeviceIndex],
 -                                                       dlh.inputGuids [inputDeviceIndex],
 -                                                       (int) sampleRate, bufferSizeSamples,
 -                                                       left, right));
 -     }
 - 
 -     enabledOutputs = outputChannels;
 -     enabledOutputs.setRange (outChannels.size(),
 -                              enabledOutputs.getHighestBit() + 1 - outChannels.size(),
 -                              false);
 - 
 -     numOutputBuffers = enabledOutputs.countNumberOfSetBits();
 -     outputBuffers = new float* [numOutputBuffers + 2];
 -     zeromem (outputBuffers, sizeof (float*) * numOutputBuffers + 2);
 -     int numOuts = 0;
 - 
 -     for (i = 0; i <= enabledOutputs.getHighestBit(); i += 2)
 -     {
 -         float* left = 0;
 -         float* right = 0;
 - 
 -         if (enabledOutputs[i])
 -             left = outputBuffers[numOuts++] = (float*) juce_calloc ((bufferSizeSamples + 16) * sizeof (float));
 - 
 -         if (enabledOutputs[i + 1])
 -             right = outputBuffers[numOuts++] = (float*) juce_calloc ((bufferSizeSamples + 16) * sizeof (float));
 - 
 -         if (left != 0 || right != 0)
 -             outChans.add (new DSoundInternalOutChannel (dlh.outputDeviceNames[outputDeviceIndex],
 -                                                         dlh.outputGuids [outputDeviceIndex],
 -                                                         (int) sampleRate, bufferSizeSamples,
 -                                                         left, right));
 -     }
 - 
 -     String error;
 - 
 -     // boost our priority while opening the devices to try to get better sync between them
 -     const int oldThreadPri = GetThreadPriority (GetCurrentThread());
 -     const int oldProcPri = GetPriorityClass (GetCurrentProcess());
 -     SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
 -     SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
 - 
 -     for (i = 0; i < outChans.size(); ++i)
 -     {
 -         error = outChans[i]->open();
 - 
 -         if (error.isNotEmpty())
 -         {
 -             error = T("Error opening ") + dlh.outputDeviceNames[i]
 -                      + T(": \"") + error + T("\"");
 -             break;
 -         }
 -     }
 - 
 -     if (error.isEmpty())
 -     {
 -         for (i = 0; i < inChans.size(); ++i)
 -         {
 -             error = inChans[i]->open();
 - 
 -             if (error.isNotEmpty())
 -             {
 -                 error = T("Error opening ") + dlh.inputDeviceNames[i]
 -                             + T(": \"") + error + T("\"");
 -                 break;
 -             }
 -         }
 -     }
 - 
 -     if (error.isEmpty())
 -     {
 -         totalSamplesOut = 0;
 - 
 -         for (i = 0; i < outChans.size(); ++i)
 -             outChans.getUnchecked(i)->synchronisePosition();
 - 
 -         for (i = 0; i < inChans.size(); ++i)
 -             inChans.getUnchecked(i)->synchronisePosition();
 - 
 -         startThread (9);
 -         sleep (10);
 - 
 -         notify();
 -     }
 -     else
 -     {
 -         log (error);
 -     }
 - 
 -     SetThreadPriority (GetCurrentThread(), oldThreadPri);
 -     SetPriorityClass (GetCurrentProcess(), oldProcPri);
 - 
 -     return error;
 - }
 - 
 - 
 - #undef log
 - 
 - #endif
 
 
  |