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_)