first try implementing CoreAudio interface
This commit is contained in:
parent
b00a423ad9
commit
4e9e5c36f0
7 changed files with 223 additions and 21 deletions
|
@ -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
|
||||
|
|
17
llcon.pro
17
llcon.pro
|
@ -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 \
|
||||
|
|
180
mac/sound.cpp
180
mac/sound.cpp
|
@ -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;
|
||||
}
|
||||
|
|
23
mac/sound.h
23
mac/sound.h
|
@ -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_)
|
||||
|
|
12
src/client.h
12
src/client.h
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue