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();
|
virtual void Stop();
|
||||||
|
|
||||||
// not implemented yet, always return one device and default string
|
// not implemented yet, always return one device and default string
|
||||||
int GetNumDev() { return 1; }
|
int GetNumDev() { return 1; }
|
||||||
QString GetDeviceName ( const int iDiD ) { return "wave mapper"; }
|
QString GetDeviceName ( const int ) { return "wave mapper"; }
|
||||||
QString SetDev ( const int iNewDev ) { return ""; } // dummy
|
QString SetDev ( const int ) { return ""; } // dummy
|
||||||
int GetDev() { return 0; }
|
int GetDev() { return 0; }
|
||||||
|
|
||||||
// these variables should be protected but cannot since we want
|
// these variables should be protected but cannot since we want
|
||||||
// to access them from the callback function
|
// to access them from the callback function
|
||||||
|
|
17
llcon.pro
17
llcon.pro
|
@ -11,6 +11,17 @@ INCLUDEPATH += src \
|
||||||
DEFINES += USE_ALLOCA \
|
DEFINES += USE_ALLOCA \
|
||||||
_REENTRANT
|
_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
|
RCC_DIR = src/res
|
||||||
RESOURCES += src/resources.qrc
|
RESOURCES += src/resources.qrc
|
||||||
|
|
||||||
|
@ -20,8 +31,7 @@ FORMS += src/llconclientdlgbase.ui \
|
||||||
src/chatdlgbase.ui \
|
src/chatdlgbase.ui \
|
||||||
src/aboutdlgbase.ui
|
src/aboutdlgbase.ui
|
||||||
|
|
||||||
HEADERS += linux/sound.h \
|
HEADERS += src/buffer.h \
|
||||||
src/buffer.h \
|
|
||||||
src/global.h \
|
src/global.h \
|
||||||
src/socket.h \
|
src/socket.h \
|
||||||
src/channel.h \
|
src/channel.h \
|
||||||
|
@ -73,8 +83,7 @@ HEADERS += linux/sound.h \
|
||||||
libs/celt/stack_alloc.h \
|
libs/celt/stack_alloc.h \
|
||||||
libs/celt/vq.h
|
libs/celt/vq.h
|
||||||
|
|
||||||
SOURCES += linux/sound.cpp \
|
SOURCES += src/buffer.cpp \
|
||||||
src/buffer.cpp \
|
|
||||||
src/main.cpp \
|
src/main.cpp \
|
||||||
src/socket.cpp \
|
src/socket.cpp \
|
||||||
src/channel.cpp \
|
src/channel.cpp \
|
||||||
|
|
180
mac/sound.cpp
180
mac/sound.cpp
|
@ -24,4 +24,182 @@
|
||||||
|
|
||||||
#include "sound.h"
|
#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_)
|
#if !defined(_SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_)
|
||||||
#define _SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_
|
#define _SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_
|
||||||
|
|
||||||
|
#include <CoreServices/CoreServices.h>
|
||||||
|
#include <AudioUnit/AudioUnit.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "soundbase.h"
|
#include "soundbase.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
@ -35,20 +37,29 @@ class CSound : public CSoundBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSound ( void (*fpNewProcessCallback) ( CVector<short>& psData, void* arg ), void* arg ) :
|
CSound ( void (*fpNewProcessCallback) ( CVector<short>& psData, void* arg ), void* arg ) :
|
||||||
CSoundBase ( true, fpNewProcessCallback, arg ) { OpenJack(); }
|
CSoundBase ( true, fpNewProcessCallback, arg ) { OpenCoreAudio(); }
|
||||||
virtual ~CSound() {}
|
virtual ~CSound() { CloseCoreAudio(); }
|
||||||
|
|
||||||
virtual int Init ( const int iNewPrefMonoBufferSize );
|
virtual int Init ( const int iNewPrefMonoBufferSize );
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
|
|
||||||
// not implemented yet, always return one device and default string
|
// not implemented yet, always return one device and default string
|
||||||
int GetNumDev() { return 1; }
|
int GetNumDev() { return 1; }
|
||||||
QString GetDeviceName ( const int iDiD ) { return "CoreAudio"; }
|
QString GetDeviceName ( const int ) { return "CoreAudio"; }
|
||||||
QString SetDev ( const int iNewDev ) { return ""; } // dummy
|
QString SetDev ( const int ) { return ""; } // dummy
|
||||||
int GetDev() { return 0; }
|
int GetDev() { return 0; }
|
||||||
|
|
||||||
protected:
|
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_)
|
#endif // !defined(_SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_)
|
||||||
|
|
12
src/client.h
12
src/client.h
|
@ -43,10 +43,14 @@
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
# include "../windows/sound.h"
|
# include "../windows/sound.h"
|
||||||
# else
|
# else
|
||||||
# include "../linux/sound.h"
|
# if defined ( __APPLE__ ) || defined ( __MACOSX )
|
||||||
# include <sched.h>
|
# include "../mac/sound.h"
|
||||||
# include <socket.h>
|
# else
|
||||||
# include <netdb.h>
|
# include "../linux/sound.h"
|
||||||
|
# include <sched.h>
|
||||||
|
# include <socket.h>
|
||||||
|
# include <netdb.h>
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -442,7 +442,7 @@ void CLlconClientDlg::OnSliderAudInFader ( int value )
|
||||||
UpdateAudioFaderSlider();
|
UpdateAudioFaderSlider();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLlconClientDlg::OnLineEditServerAddrTextChanged ( const QString sNewText )
|
void CLlconClientDlg::OnLineEditServerAddrTextChanged ( const QString )
|
||||||
{
|
{
|
||||||
// if the maximum number of items in the combo box is reached,
|
// 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
|
// delete the last item so that the new item can be added (first
|
||||||
|
|
|
@ -114,7 +114,7 @@ public slots:
|
||||||
void OnChatTextReceived ( QString strChatText );
|
void OnChatTextReceived ( QString strChatText );
|
||||||
void OnNewLocalInputText ( QString strChatText )
|
void OnNewLocalInputText ( QString strChatText )
|
||||||
{ pClient->SendTextMess ( strChatText ); }
|
{ pClient->SendTextMess ( strChatText ); }
|
||||||
void OnLineEditServerAddrTextChanged ( const QString sNewText );
|
void OnLineEditServerAddrTextChanged ( const QString );
|
||||||
void OnLineEditServerAddrActivated ( int index );
|
void OnLineEditServerAddrActivated ( int index );
|
||||||
void OnDisconnected();
|
void OnDisconnected();
|
||||||
void OnStopped();
|
void OnStopped();
|
||||||
|
|
Loading…
Reference in a new issue