From ac388f0c1c465683ef924d41a6223209b35d2f97 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Sat, 28 Dec 2013 12:00:21 +0000 Subject: [PATCH] added some initial Android files --- Jamulus.pro | 11 +- android/AndroidManifest.xml | 40 +++ android/sound.cpp | 659 ++++++++++++++++++++++++++++++++++++ android/sound.h | 112 ++++++ 4 files changed, 821 insertions(+), 1 deletion(-) create mode 100644 android/AndroidManifest.xml create mode 100644 android/sound.cpp create mode 100644 android/sound.h diff --git a/Jamulus.pro b/Jamulus.pro index 6879cd9b..36d70fef 100755 --- a/Jamulus.pro +++ b/Jamulus.pro @@ -48,6 +48,12 @@ win32 { -framework CoreAudio \ -framework AudioToolbox \ -framework AudioUnit +} else:android { + HEADERS += android/sound.h + SOURCES += android/sound.cpp + LIBS += -lOpenSLES + ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android + OTHER_FILES += android/AndroidManifest.xml } else:unix { # we assume that stdint.h is always present in a Linux system DEFINES += HAVE_STDINT_H @@ -70,7 +76,10 @@ win32 { windows/sound.h \ windows/sound.cpp \ windows/mainicon.rc \ - windows/mainicon.ico + windows/mainicon.ico \ + android/AndroidManifest.xml \ + android/sound.h \ + android/sound.cpp } RCC_DIR = src/res diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml new file mode 100644 index 00000000..74a43c5c --- /dev/null +++ b/android/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/sound.cpp b/android/sound.cpp new file mode 100644 index 00000000..032d1d3a --- /dev/null +++ b/android/sound.cpp @@ -0,0 +1,659 @@ +/******************************************************************************\ + * Copyright (c) 2004-2014 + * + * Author(s): + * Volker Fischer + * + ****************************************************************************** + * + * This program is free software; you can redistribute it and/or modify it 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. + * + * This program 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 + * this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +\******************************************************************************/ + +#include "sound.h" + + +/* Implementation *************************************************************/ +CSound::CSound ( void (*fpNewProcessCallback) ( CVector& psData, void* arg ), void* arg ) : + CSoundBase ( "OpenSL", true, fpNewProcessCallback, arg ) +{ + SLObjectItf engineObject; + SLEngineItf engine; + SLObjectItf outputMixObject; + SLObjectItf playerObject; + SLPlayItf player; + SLAndroidSimpleBufferQueueItf playerSimpleBufQueue; + + // create the OpenSL root engine object + slCreateEngine ( &engineObject, + 0, + nullptr, + 0, + nullptr, + nullptr ); + + // realize the engine + (*engineObject)->Realize ( engineObject, + SL_BOOLEAN_FALSE ); + + // get the engine interface (required to create other objects) + (*engineObject)->GetInterface ( engineObject, + SL_IID_ENGINE, + &engine ); + + // create the main output mix + const SLInterfaceID engineIds[] = { SL_IID_VOLUME }; + const SLboolean engineReq[] = { SL_BOOLEAN_FALSE }; + + (*engine)->CreateOutputMix ( engine, + &outputMixObject, + 1, + engineIds, + engineReq ); + + (*outputMixObject)->Realize ( outputMixObject, + SL_BOOLEAN_FALSE ); + + // configure the buffer queue. + SLDataLocator_AndroidSimpleBufferQueue bufferQueue; + bufferQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; + bufferQueue.numBuffers = 1; + + // set up stream format + SLDataFormat_PCM streamFormat; + streamFormat.formatType = SL_DATAFORMAT_PCM; + streamFormat.numChannels = 1; + streamFormat.samplesPerSec = SYSTEM_SAMPLE_RATE_HZ * 1000; // unit is mHz + streamFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; + streamFormat.containerSize = 16; + streamFormat.channelMask = SL_SPEAKER_FRONT_CENTER; + streamFormat.endianness = SL_BYTEORDER_LITTLEENDIAN; + + // configure the audio (data) source + SLDataSource dataSource; + dataSource.pLocator = &bufferQueue; + dataSource.pFormat = &streamFormat; + + // configure the output mix + SLDataLocator_OutputMix outputMix; + outputMix.locatorType = SL_DATALOCATOR_OUTPUTMIX; + outputMix.outputMix = outputMixObject; + + // configure the audio (data) sink + SLDataSink dataSink; + dataSink.pLocator = &outputMix; + dataSink.pFormat = nullptr; + + // create the audio player + const SLInterfaceID playerIds[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE }; + const SLboolean playerReq[] = { SL_BOOLEAN_TRUE }; + + (*engine)->CreateAudioPlayer ( engine, + &playerObject, + &dataSource, + &dataSink, + 1, + playerIds, + playerReq ); + + // realize the audio player + (*playerObject)->Realize ( playerObject, + SL_BOOLEAN_FALSE ); + + // get the audio player interface + (*playerObject)->GetInterface ( playerObject, + SL_IID_PLAY, + &player ); + + // get the audio player simple buffer queue interface + (*playerObject)->GetInterface ( playerObject, + SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &playerSimpleBufQueue ); + + + + +/* + + // set up a callback struct for new input data + inputCallbackStruct.inputProc = processInput; + inputCallbackStruct.inputProcRefCon = this; + + // set up a callback struct for new output data + outputCallbackStruct.inputProc = processOutput; + outputCallbackStruct.inputProcRefCon = this; + + // allocate memory for buffer struct + pBufferList = (AudioBufferList*) malloc ( offsetof ( AudioBufferList, + mBuffers[0] ) + sizeof ( AudioBuffer ) ); + + // open the default unit + ComponentDescription desc; + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_HALOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + Component comp = FindNextComponent ( NULL, &desc ); + if ( comp == NULL ) + { + throw CGenErr ( tr ( "No CoreAudio next component found" ) ); + } + + if ( OpenAComponent ( comp, &audioInputUnit ) ) + { + throw CGenErr ( tr ( "CoreAudio creating input component instance failed" ) ); + } + + if ( OpenAComponent ( comp, &audioOutputUnit ) ) + { + throw CGenErr ( tr ( "CoreAudio creating output component instance failed" ) ); + } + + // we enable input and disable output for input component + UInt32 enableIO = 1; + AudioUnitSetProperty ( audioInputUnit, + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Input, + 1, // input element + &enableIO, + sizeof ( enableIO ) ); + + enableIO = 0; + AudioUnitSetProperty ( audioInputUnit, + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Output, + 0, // output element + &enableIO, + sizeof ( enableIO ) ); + + // set up a callback function for new input data + if ( AudioUnitSetProperty ( audioInputUnit, + kAudioOutputUnitProperty_SetInputCallback, + kAudioUnitScope_Global, + 0, + &inputCallbackStruct, + sizeof ( inputCallbackStruct ) ) ) + { + throw CGenErr ( tr ( "CoreAudio audio unit set property failed" ) ); + } + + // set input stream format + if ( AudioUnitSetProperty ( audioInputUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 1, + &streamFormat, + sizeof ( streamFormat ) ) ) + { + throw CGenErr ( tr ( "CoreAudio stream format set property failed" ) ); + } + + + // set up a callback function for new output data + if ( AudioUnitSetProperty ( audioOutputUnit, + kAudioUnitProperty_SetRenderCallback, + kAudioUnitScope_Global, + 0, + &outputCallbackStruct, + sizeof ( outputCallbackStruct ) ) ) + { + throw CGenErr ( tr ( "CoreAudio audio unit set property failed" ) ); + } + + // ste output stream format + if ( AudioUnitSetProperty ( audioOutputUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, + &streamFormat, + sizeof ( streamFormat ) ) ) + { + throw CGenErr ( tr ( "CoreAudio stream format set property failed" ) ); + } + + + // Get available input/output devices -------------------------------------- + UInt32 iPropertySize; + + // first get property size of devices array and allocate memory + AudioHardwareGetPropertyInfo ( kAudioHardwarePropertyDevices, + &iPropertySize, + NULL ); + + AudioDeviceID* audioDevices = (AudioDeviceID*) malloc ( iPropertySize ); + + // now actually query all devices present in the system + AudioHardwareGetProperty ( kAudioHardwarePropertyDevices, + &iPropertySize, + audioDevices ); + + // calculate device count based on size of returned data array + const UInt32 deviceCount = ( iPropertySize / sizeof ( AudioDeviceID ) ); + + // always add system default devices for input and output as first entry + lNumDevs = 0; + strDriverNames[lNumDevs] = "System Default In/Out Devices"; + + iPropertySize = sizeof ( AudioDeviceID ); + if ( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultInputDevice, + &iPropertySize, + &audioInputDevice[lNumDevs] ) ) + { + throw CGenErr ( tr ( "CoreAudio input AudioHardwareGetProperty call failed. " + "It seems that no sound card is available in the system." ) ); + } + + iPropertySize = sizeof ( AudioDeviceID ); + if ( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultOutputDevice, + &iPropertySize, + &audioOutputDevice[lNumDevs] ) ) + { + throw CGenErr ( tr ( "CoreAudio output AudioHardwareGetProperty call failed. " + "It seems that no sound card is available in the system." ) ); + } + + lNumDevs++; // next device + + // add detected devices (also check for maximum allowed sound cards!) + // + // we add combined entries for input and output for each device so that we + // do not need two combo boxes in the GUI for input and output (therefore + // all possible combinations are required) + for ( UInt32 i = 0; ( i < deviceCount ) && ( i < MAX_NUMBER_SOUND_CARDS - 1 ); i++ ) + { + for ( UInt32 j = 0; ( j < deviceCount ) && ( j < MAX_NUMBER_SOUND_CARDS - 1 ); j++ ) + { + // get device infos for both current devices + QString strDeviceName_i; + QString strDeviceName_j; + bool bIsInput_i; + bool bIsInput_j; + bool bIsOutput_i; + bool bIsOutput_j; + + GetAudioDeviceInfos ( audioDevices[i], + strDeviceName_i, + bIsInput_i, + bIsOutput_i ); + + GetAudioDeviceInfos ( audioDevices[j], + strDeviceName_j, + bIsInput_j, + bIsOutput_j ); + + // check if i device is input and j device is output + if ( bIsInput_i && bIsOutput_j ) + { + strDriverNames[lNumDevs] = "in: " + + strDeviceName_i + "/out: " + + strDeviceName_j; + + // store audio device IDs + audioInputDevice[lNumDevs] = audioDevices[i]; + audioOutputDevice[lNumDevs] = audioDevices[j]; + + lNumDevs++; // next device + } + } + } + + // init device index as not initialized (invalid) + lCurDev = INVALID_SNC_CARD_DEVICE; +*/ +} + +/* +void CSound::GetAudioDeviceInfos ( const AudioDeviceID DeviceID, + QString& strDeviceName, + bool& bIsInput, + bool& bIsOutput ) +{ + // get property name + UInt32 iPropertySize = sizeof ( CFStringRef ); + CFStringRef sPropertyStringValue; + + AudioDeviceGetProperty ( DeviceID, + 0, + false, + kAudioObjectPropertyName, + &iPropertySize, + &sPropertyStringValue ); + + // convert CFString in c-string (quick hack!) and then in QString + char* sC_strPropValue = + (char*) malloc ( CFStringGetLength ( sPropertyStringValue ) + 1 ); + + CFStringGetCString ( sPropertyStringValue, + sC_strPropValue, + CFStringGetLength ( sPropertyStringValue ) + 1, + kCFStringEncodingISOLatin1 ); + + strDeviceName = sC_strPropValue; + + // check if device is input or output or both (is that possible?) + // we do this by trying to set the current device for the audio unit + // with the parameter input and output and then we simply check the + // error/ok result + bIsInput = !AudioUnitSetProperty ( audioInputUnit, + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, + 1, + &DeviceID, + sizeof ( AudioDeviceID ) ); + + bIsOutput = !AudioUnitSetProperty ( audioOutputUnit, + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, + 0, + &DeviceID, + sizeof ( AudioDeviceID ) ); +} +*/ + +/* +QString CSound::LoadAndInitializeDriver ( int iDriverIdx ) +{ + // set input device + if ( AudioUnitSetProperty ( audioInputUnit, + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, + 1, + &audioInputDevice[iDriverIdx], + sizeof ( AudioDeviceID ) ) ) + { + throw CGenErr ( tr ( "CoreAudio input AudioUnitSetProperty call failed" ) ); + } + + // set output device + if ( AudioUnitSetProperty ( audioOutputUnit, + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, + 0, + &audioOutputDevice[iDriverIdx], + sizeof ( AudioDeviceID ) ) ) + { + throw CGenErr ( tr ( "CoreAudio output AudioUnitSetProperty call failed" ) ); + } + + // check device capabilities if it fullfills our requirements + const QString strStat = + CheckDeviceCapabilities ( audioInputUnit, audioOutputUnit ); + + // check if device is capable + if ( strStat.isEmpty() ) + { + // store ID of selected driver if initialization was successful + lCurDev = iDriverIdx; + + // setup callback for xruns (only for input is enough) + AudioDeviceAddPropertyListener ( audioInputDevice[lCurDev], + 0, + true, + kAudioDeviceProcessorOverload, + deviceNotification, + this ); + } + + return strStat; +} +*/ + +/* +QString CSound::CheckDeviceCapabilities ( ComponentInstance& NewAudioInputUnit, + ComponentInstance& NewAudioOutputUnit ) +{ + UInt32 size; + + // check input device sample rate + size = sizeof ( Float64 ); + Float64 inputSampleRate; + AudioUnitGetProperty ( NewAudioInputUnit, + kAudioUnitProperty_SampleRate, + kAudioUnitScope_Input, + 1, + &inputSampleRate, + &size ); + + if ( static_cast ( inputSampleRate ) != SYSTEM_SAMPLE_RATE_HZ ) + { + return QString ( tr ( "Current system audio input device sample " + "rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in " + "Applications->Utilities and try to set a sample rate of %2 Hz." ) ).arg ( + static_cast ( inputSampleRate ) ).arg ( SYSTEM_SAMPLE_RATE_HZ ); + } + + // check output device sample rate + size = sizeof ( Float64 ); + Float64 outputSampleRate; + AudioUnitGetProperty ( NewAudioOutputUnit, + kAudioUnitProperty_SampleRate, + kAudioUnitScope_Output, + 0, + &outputSampleRate, + &size ); + + if ( static_cast ( outputSampleRate ) != SYSTEM_SAMPLE_RATE_HZ ) + { + return QString ( tr ( "Current system audio output device sample " + "rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in " + "Applications->Utilities and try to set a sample rate of %2 Hz." ) ).arg ( + static_cast ( outputSampleRate ) ).arg ( SYSTEM_SAMPLE_RATE_HZ ); + } + + // everything is ok, return empty string for "no error" case + return ""; +} +*/ + +void CSound::CloseOpenSL() +{ + +/* + // clean up + AudioUnitUninitialize ( audioInputUnit ); + AudioUnitUninitialize ( audioOutputUnit ); + CloseComponent ( audioInputUnit ); + CloseComponent ( audioOutputUnit ); +*/ +} + +void CSound::Start() +{ + +/* + // start the rendering + AudioOutputUnitStart ( audioInputUnit ); + AudioOutputUnitStart ( audioOutputUnit ); +*/ + + // call base class + CSoundBase::Start(); +} + +void CSound::Stop() +{ + +/* + // stop the audio stream + AudioOutputUnitStop ( audioInputUnit ); + AudioOutputUnitStop ( audioOutputUnit ); +*/ + + // call base class + CSoundBase::Stop(); +} + +int CSound::Init ( const int iNewPrefMonoBufferSize ) +{ + +/* + UInt32 iActualMonoBufferSize; + + // Error message string: in case buffer sizes on input and output cannot be + // set to the same value + const QString strErrBufSize = tr ( "The buffer sizes of the current " + "input and output audio device cannot be set to a common value. Please " + "choose other input/output audio devices in your system settings." ); + + // try to set input buffer size + iActualMonoBufferSize = + SetBufferSize ( audioInputDevice[lCurDev], true, iNewPrefMonoBufferSize ); + + if ( iActualMonoBufferSize != static_cast ( iNewPrefMonoBufferSize ) ) + { + // try to set the input buffer size to the output so that we + // have a matching pair + if ( SetBufferSize ( audioOutputDevice[lCurDev], false, iActualMonoBufferSize ) != + iActualMonoBufferSize ) + { + throw CGenErr ( strErrBufSize ); + } + } + else + { + // try to set output buffer size + if ( SetBufferSize ( audioOutputDevice[lCurDev], false, iNewPrefMonoBufferSize ) != + static_cast ( iNewPrefMonoBufferSize ) ) + { + throw CGenErr ( strErrBufSize ); + } + } + + // store buffer size + iCoreAudioBufferSizeMono = iActualMonoBufferSize; + + // init base class + CSoundBase::Init ( iCoreAudioBufferSizeMono ); + + // set internal buffer size value and calculate stereo buffer size + iCoreAudioBufferSizeStero = 2 * iCoreAudioBufferSizeMono; + + // create memory for intermediate audio buffer + vecsTmpAudioSndCrdStereo.Init ( iCoreAudioBufferSizeStero ); + + // fill audio unit buffer struct + pBufferList->mNumberBuffers = 1; + pBufferList->mBuffers[0].mNumberChannels = 2; // stereo + pBufferList->mBuffers[0].mDataByteSize = iCoreAudioBufferSizeMono * 4; // 2 bytes, 2 channels + pBufferList->mBuffers[0].mData = &vecsTmpAudioSndCrdStereo[0]; + + // initialize units + if ( AudioUnitInitialize ( audioInputUnit ) ) + { + throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) ); + } + + if ( AudioUnitInitialize ( audioOutputUnit ) ) + { + throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) ); + } +*/ + + return iOpenSLBufferSizeMono; +} + +/* +UInt32 CSound::SetBufferSize ( AudioDeviceID& audioDeviceID, + const bool bIsInput, + UInt32 iPrefBufferSize ) +{ + // first set the value + UInt32 iSizeBufValue = sizeof ( UInt32 ); + AudioDeviceSetProperty ( audioDeviceID, + NULL, + 0, + bIsInput, + kAudioDevicePropertyBufferFrameSize, + iSizeBufValue, + &iPrefBufferSize ); + + // read back which value is actually used + UInt32 iActualMonoBufferSize; + AudioDeviceGetProperty ( audioDeviceID, + 0, + bIsInput, + kAudioDevicePropertyBufferFrameSize, + &iSizeBufValue, + &iActualMonoBufferSize ); + + return iActualMonoBufferSize; +} +*/ + +/* +OSStatus CSound::deviceNotification ( AudioDeviceID, + UInt32, + Boolean, + AudioDevicePropertyID inPropertyID, + void* inRefCon ) +{ + CSound* pSound = reinterpret_cast ( inRefCon ); + + if ( inPropertyID == kAudioDeviceProcessorOverload ) + { + // xrun handling (it is important to act on xruns under CoreAudio + // since it seems that the xrun situation stays stable for a + // while and would give you a long time bad audio + pSound->EmitReinitRequestSignal ( RS_ONLY_RESTART ); + } + + return noErr; +} + +OSStatus CSound::processInput ( void* inRefCon, + AudioUnitRenderActionFlags* ioActionFlags, + const AudioTimeStamp* inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ) +{ + CSound* pSound = reinterpret_cast ( inRefCon ); + + QMutexLocker locker ( &pSound->Mutex ); + + // get the new audio data + AudioUnitRender ( pSound->audioInputUnit, + ioActionFlags, + inTimeStamp, + inBusNumber, + inNumberFrames, + pSound->pBufferList ); + + // call processing callback function + pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo ); + + return noErr; +} + +OSStatus CSound::processOutput ( void* inRefCon, + AudioUnitRenderActionFlags*, + const AudioTimeStamp*, + UInt32, + UInt32, + AudioBufferList* ioData ) +{ + CSound* pSound = reinterpret_cast ( inRefCon ); + + QMutexLocker locker ( &pSound->Mutex ); + + memcpy ( ioData->mBuffers[0].mData, + &pSound->vecsTmpAudioSndCrdStereo[0], + pSound->pBufferList->mBuffers[0].mDataByteSize); + + return noErr; +} +*/ diff --git a/android/sound.h b/android/sound.h new file mode 100644 index 00000000..4189ada3 --- /dev/null +++ b/android/sound.h @@ -0,0 +1,112 @@ +/******************************************************************************\ + * Copyright (c) 2004-2014 + * + * Author(s): + * Volker Fischer + * + ****************************************************************************** + * + * This program is free software; you can redistribute it and/or modify it 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. + * + * This program 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 + * this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +\******************************************************************************/ + +#if !defined(_SOUND_H__9518A621345F78_3638457H73245GUIG9__INCLUDED_) +#define _SOUND_H__9518A621345F78_3638457H73245GUIG9__INCLUDED_ + +#include +#include +#include "soundbase.h" +#include "global.h" + + +/* Classes ********************************************************************/ +class CSound : public CSoundBase +{ +public: + CSound ( void (*fpNewProcessCallback) ( CVector& psData, void* arg ), void* arg ); + virtual ~CSound() { CloseOpenSL(); } + + virtual int Init ( const int iNewPrefMonoBufferSize ); + virtual void Start(); + virtual void Stop(); + + // these variables should be protected but cannot since we want + // to access them from the callback function + CVector vecsTmpAudioSndCrdStereo; + int iOpenSLBufferSizeMono; + int iOpenSLBufferSizeStero; + +protected: +/* + virtual QString LoadAndInitializeDriver ( int iIdx ); + + QString CheckDeviceCapabilities ( ComponentInstance& NewAudioInputUnit, + ComponentInstance& NewAudioOutputUnit ); +*/ + + void CloseOpenSL(); + +/* + UInt32 SetBufferSize ( AudioDeviceID& audioDeviceID, + const bool bIsInput, + UInt32 iPrefBufferSize ); + + void GetAudioDeviceInfos ( const AudioDeviceID DeviceID, + QString& strDeviceName, + bool& bIsInput, + bool& bIsOutput ); +*/ + +/* + // callbacks + static OSStatus deviceNotification ( AudioDeviceID, + UInt32, + Boolean, + AudioDevicePropertyID inPropertyID, + void* inRefCon ); + + static OSStatus processInput ( void* inRefCon, + AudioUnitRenderActionFlags* ioActionFlags, + const AudioTimeStamp* inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ); + + static OSStatus processOutput ( void* inRefCon, + AudioUnitRenderActionFlags*, + const AudioTimeStamp*, + UInt32, + UInt32, + AudioBufferList* ioData ); +*/ + +/* + AudioStreamBasicDescription streamFormat; + + AURenderCallbackStruct inputCallbackStruct; + AURenderCallbackStruct outputCallbackStruct; + + ComponentInstance audioInputUnit; + AudioDeviceID audioInputDevice[MAX_NUMBER_SOUND_CARDS]; + ComponentInstance audioOutputUnit; + AudioDeviceID audioOutputDevice[MAX_NUMBER_SOUND_CARDS]; + + AudioBufferList* pBufferList; + + QMutex Mutex; +*/ +}; + +#endif // !defined(_SOUND_H__9518A621345F78_3638457H73245GUIG9__INCLUDED_)