first try implementing CoreAudio interface

This commit is contained in:
Volker Fischer 2010-03-05 20:19:12 +00:00
parent b00a423ad9
commit 4e9e5c36f0
7 changed files with 223 additions and 21 deletions

View File

@ -67,10 +67,10 @@ public:
virtual void Stop();
// not implemented yet, always return one device and default string
int GetNumDev() { return 1; }
QString GetDeviceName ( const int iDiD ) { return "wave mapper"; }
QString SetDev ( const int iNewDev ) { return ""; } // dummy
int GetDev() { return 0; }
int GetNumDev() { return 1; }
QString GetDeviceName ( const int ) { return "wave mapper"; }
QString SetDev ( const int ) { return ""; } // dummy
int GetDev() { return 0; }
// these variables should be protected but cannot since we want
// to access them from the callback function

View File

@ -11,6 +11,17 @@ INCLUDEPATH += src \
DEFINES += USE_ALLOCA \
_REENTRANT
macx {
HEADERS += mac/sound.h
SOURCES += mac/sound.cpp
LIBS += -framework CoreFoundation \
-framework CoreServices \
-framework CoreAudio \
-framework AudioToolbox \
-framework AudioUnit
}
RCC_DIR = src/res
RESOURCES += src/resources.qrc
@ -20,8 +31,7 @@ FORMS += src/llconclientdlgbase.ui \
src/chatdlgbase.ui \
src/aboutdlgbase.ui
HEADERS += linux/sound.h \
src/buffer.h \
HEADERS += src/buffer.h \
src/global.h \
src/socket.h \
src/channel.h \
@ -73,8 +83,7 @@ HEADERS += linux/sound.h \
libs/celt/stack_alloc.h \
libs/celt/vq.h
SOURCES += linux/sound.cpp \
src/buffer.cpp \
SOURCES += src/buffer.cpp \
src/main.cpp \
src/socket.cpp \
src/channel.cpp \

View File

@ -24,4 +24,182 @@
#include "sound.h"
// TODO implementation (use Jack interface as a reference)
/* Implementation *************************************************************/
void CSound::OpenCoreAudio()
{
// open the default output unit
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = 0;
AudioComponent comp = AudioComponentFindNext ( NULL, &desc );
if ( comp == NULL )
{
throw CGenErr ( tr ( "No CoreAudio next component found" ) );
}
if ( AudioComponentInstanceNew ( comp, &gOutputUnit ) )
{
throw CGenErr ( tr ( "CoreAudio creating component instance failed" ) );
}
// set up a callback function to generate output to the output unit
AURenderCallbackStruct input;
input.inputProc = process;
input.inputProcRefCon = this;
if ( AudioUnitSetProperty ( gOutputUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0,
&input,
sizeof(input) ) )
{
throw CGenErr ( tr ( "CoreAudio audio unit set property failed" ) );
}
// set up stream format
AudioStreamBasicDescription streamFormat;
streamFormat.mSampleRate = SYSTEM_SAMPLE_RATE;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger;
streamFormat.mFramesPerPacket = 1;
streamFormat.mChannelsPerFrame = 1;
streamFormat.mBitsPerChannel = 16;
streamFormat.mBytesPerPacket = 2;
streamFormat.mBytesPerFrame = 2;
if ( AudioUnitSetProperty ( gOutputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&streamFormat,
sizeof(streamFormat) ) )
{
throw CGenErr ( tr ( "CoreAudio stream format set property failed" ) );
}
// initialize unit
if ( AudioUnitInitialize ( gOutputUnit ) )
{
throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) );
}
}
void CSound::CloseCoreAudio()
{
// clean up "gOutputUnit"
AudioUnitUninitialize ( gOutputUnit );
CloseComponent ( gOutputUnit );
}
void CSound::Start()
{
// start the rendering
if ( AudioOutputUnitStart ( gOutputUnit ) )
{
throw CGenErr ( tr ( "CoreAudio starting failed" ) );
}
}
void CSound::Stop()
{
// stop the audio stream
if ( AudioOutputUnitStop ( gOutputUnit ) )
{
throw CGenErr ( tr ( "CoreAudio stopping failed" ) );
}
}
int CSound::Init ( const int iNewPrefMonoBufferSize )
{
/*
// try setting buffer size
// TODO seems not to work! -> no audio after this operation!
//jack_set_buffer_size ( pJackClient, iNewPrefMonoBufferSize );
// get actual buffer size
iJACKBufferSizeMono = jack_get_buffer_size ( pJackClient );
// init base clasee
CSoundBase::Init ( iJACKBufferSizeMono );
// set internal buffer size value and calculate stereo buffer size
iJACKBufferSizeStero = 2 * iJACKBufferSizeMono;
// create memory for intermediate audio buffer
vecsTmpAudioSndCrdStereo.Init ( iJACKBufferSizeStero );
return iJACKBufferSizeMono;
*/
// TEST
return 256;
}
OSStatus CSound::process ( void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData )
{
CSound* pSound = reinterpret_cast<CSound*> ( inRefCon );
/*
// get input data pointer
jack_default_audio_sample_t* in_left =
(jack_default_audio_sample_t*) jack_port_get_buffer (
pSound->input_port_left, nframes );
jack_default_audio_sample_t* in_right =
(jack_default_audio_sample_t*) jack_port_get_buffer (
pSound->input_port_right, nframes );
// copy input data
for ( i = 0; i < pSound->iJACKBufferSizeMono; i++ )
{
pSound->vecsTmpAudioSndCrdStereo[2 * i] = (short) ( in_left[i] * _MAXSHORT );
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = (short) ( in_right[i] * _MAXSHORT );
}
// call processing callback function
pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo );
// get output data pointer
jack_default_audio_sample_t* out_left =
(jack_default_audio_sample_t*) jack_port_get_buffer (
pSound->output_port_left, nframes );
jack_default_audio_sample_t* out_right =
(jack_default_audio_sample_t*) jack_port_get_buffer (
pSound->output_port_right, nframes );
// copy output data
for ( i = 0; i < pSound->iJACKBufferSizeMono; i++ )
{
out_left[i] = (jack_default_audio_sample_t)
pSound->vecsTmpAudioSndCrdStereo[2 * i] / _MAXSHORT;
out_right[i] = (jack_default_audio_sample_t)
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] / _MAXSHORT;
}
*/
/*
ioData->mBuffers[0].mDataByteSize = 2048;
ioData->mBuffers[0].mData = lbuf;
ioData->mBuffers[0].mNumberChannels = 1;
*/
// TEST
printf ( "processing Core Audio\n" );
return noErr;
}

View File

@ -25,6 +25,8 @@
#if !defined(_SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_)
#define _SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_
#include <CoreServices/CoreServices.h>
#include <AudioUnit/AudioUnit.h>
#include "util.h"
#include "soundbase.h"
#include "global.h"
@ -35,20 +37,29 @@ class CSound : public CSoundBase
{
public:
CSound ( void (*fpNewProcessCallback) ( CVector<short>& psData, void* arg ), void* arg ) :
CSoundBase ( true, fpNewProcessCallback, arg ) { OpenJack(); }
virtual ~CSound() {}
CSoundBase ( true, fpNewProcessCallback, arg ) { OpenCoreAudio(); }
virtual ~CSound() { CloseCoreAudio(); }
virtual int Init ( const int iNewPrefMonoBufferSize );
virtual void Start();
virtual void Stop();
// not implemented yet, always return one device and default string
int GetNumDev() { return 1; }
QString GetDeviceName ( const int iDiD ) { return "CoreAudio"; }
QString SetDev ( const int iNewDev ) { return ""; } // dummy
int GetDev() { return 0; }
int GetNumDev() { return 1; }
QString GetDeviceName ( const int ) { return "CoreAudio"; }
QString SetDev ( const int ) { return ""; } // dummy
int GetDev() { return 0; }
protected:
void OpenCoreAudio();
void CloseCoreAudio();
// callbacks
static OSStatus process ( void* inRefCon,AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList* ioData );
AudioUnit gOutputUnit;
};
#endif // !defined(_SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_)

View File

@ -43,10 +43,14 @@
# ifdef _WIN32
# include "../windows/sound.h"
# else
# include "../linux/sound.h"
# include <sched.h>
# include <socket.h>
# include <netdb.h>
# if defined ( __APPLE__ ) || defined ( __MACOSX )
# include "../mac/sound.h"
# else
# include "../linux/sound.h"
# include <sched.h>
# include <socket.h>
# include <netdb.h>
# endif
# endif
#endif

View File

@ -442,7 +442,7 @@ void CLlconClientDlg::OnSliderAudInFader ( int value )
UpdateAudioFaderSlider();
}
void CLlconClientDlg::OnLineEditServerAddrTextChanged ( const QString sNewText )
void CLlconClientDlg::OnLineEditServerAddrTextChanged ( const QString )
{
// if the maximum number of items in the combo box is reached,
// delete the last item so that the new item can be added (first

View File

@ -114,7 +114,7 @@ public slots:
void OnChatTextReceived ( QString strChatText );
void OnNewLocalInputText ( QString strChatText )
{ pClient->SendTextMess ( strChatText ); }
void OnLineEditServerAddrTextChanged ( const QString sNewText );
void OnLineEditServerAddrTextChanged ( const QString );
void OnLineEditServerAddrActivated ( int index );
void OnDisconnected();
void OnStopped();