some cleanup and preperations for callback based audio interface
This commit is contained in:
parent
5917ead5e6
commit
71598931e2
3 changed files with 199 additions and 183 deletions
188
src/client.cpp
188
src/client.cpp
|
@ -170,6 +170,101 @@ void CClient::OnProtocolStatus ( bool bOk )
|
|||
}
|
||||
}
|
||||
|
||||
void CClient::Start()
|
||||
{
|
||||
// init object
|
||||
try
|
||||
{
|
||||
Init();
|
||||
}
|
||||
catch ( CGenErr generr )
|
||||
{
|
||||
// TODO better error management -> should be catched in main thread
|
||||
// problem: how to catch errors in a different thread...?
|
||||
|
||||
// quick hack solution
|
||||
QMessageBox::critical ( 0, APP_NAME, generr.GetErrorText(), "Quit", 0 );
|
||||
exit ( 0 );
|
||||
}
|
||||
|
||||
// enable channel
|
||||
Channel.SetEnable ( true );
|
||||
|
||||
// start the audio working thread with hightest possible priority
|
||||
start ( QThread::TimeCriticalPriority );
|
||||
}
|
||||
|
||||
void CClient::Stop()
|
||||
{
|
||||
// set flag so that thread can leave the main loop
|
||||
bRun = false;
|
||||
|
||||
// give thread some time to terminate
|
||||
wait ( 5000 );
|
||||
|
||||
// disable channel
|
||||
Channel.SetEnable ( false );
|
||||
|
||||
// disable sound interface
|
||||
Sound.Close();
|
||||
|
||||
// reset current signal level and LEDs
|
||||
SignalLevelMeter.Reset();
|
||||
PostWinMessage ( MS_RESET_ALL, 0 );
|
||||
}
|
||||
|
||||
void CClient::run()
|
||||
{
|
||||
// Set thread priority (The working thread should have a higher
|
||||
// priority than the GUI)
|
||||
#ifdef _WIN32
|
||||
SetThreadPriority ( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
|
||||
#else
|
||||
/*
|
||||
// set the process to realtime privs, taken from
|
||||
// "http://www.gardena.net/benno/linux/audio" but does not seem to work,
|
||||
// maybe a problem with user rights
|
||||
struct sched_param schp;
|
||||
memset ( &schp, 0, sizeof ( schp ) );
|
||||
schp.sched_priority = sched_get_priority_max ( SCHED_FIFO );
|
||||
sched_setscheduler ( 0, SCHED_FIFO, &schp );
|
||||
*/
|
||||
#endif
|
||||
|
||||
// main loop of working thread
|
||||
bRun = true;
|
||||
while ( bRun )
|
||||
{
|
||||
// get audio from sound card (blocking function)
|
||||
if ( Sound.Read ( vecsAudioSndCrdStereo ) )
|
||||
{
|
||||
PostWinMessage ( MS_SOUND_IN, MUL_COL_LED_RED );
|
||||
}
|
||||
else
|
||||
{
|
||||
PostWinMessage ( MS_SOUND_IN, MUL_COL_LED_GREEN );
|
||||
}
|
||||
|
||||
// process audio data
|
||||
ProcessAudioData ( vecsAudioSndCrdStereo );
|
||||
|
||||
// play the new block
|
||||
if ( Sound.Write ( vecsAudioSndCrdStereo ) )
|
||||
{
|
||||
PostWinMessage ( MS_SOUND_OUT, MUL_COL_LED_RED );
|
||||
}
|
||||
else
|
||||
{
|
||||
PostWinMessage ( MS_SOUND_OUT, MUL_COL_LED_GREEN );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void CClient::Init()
|
||||
{
|
||||
// set block size (in samples)
|
||||
|
@ -205,65 +300,14 @@ void CClient::Init()
|
|||
AudioReverb.Clear();
|
||||
}
|
||||
|
||||
void CClient::run()
|
||||
void CClient::ProcessAudioData ( CVector<short>& vecsStereoSndCrd )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// Set thread priority (The working thread should have a higher
|
||||
// priority than the GUI)
|
||||
#ifdef _WIN32
|
||||
SetThreadPriority ( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
|
||||
#else
|
||||
/*
|
||||
// set the process to realtime privs, taken from
|
||||
// "http://www.gardena.net/benno/linux/audio" but does not seem to work,
|
||||
// maybe a problem with user rights
|
||||
struct sched_param schp;
|
||||
memset ( &schp, 0, sizeof ( schp ) );
|
||||
schp.sched_priority = sched_get_priority_max ( SCHED_FIFO );
|
||||
sched_setscheduler ( 0, SCHED_FIFO, &schp );
|
||||
*/
|
||||
#endif
|
||||
|
||||
// init object
|
||||
try
|
||||
{
|
||||
Init();
|
||||
}
|
||||
catch ( CGenErr generr )
|
||||
{
|
||||
// TODO better error management -> should be catched in main thread
|
||||
// problem: how to catch errors in a different thread...?
|
||||
|
||||
// quick hack solution
|
||||
QMessageBox::critical ( 0, APP_NAME, generr.GetErrorText(), "Quit", 0 );
|
||||
exit ( 0 );
|
||||
}
|
||||
|
||||
|
||||
// runtime phase -----------------------------------------------------------
|
||||
// enable channel
|
||||
Channel.SetEnable ( true );
|
||||
|
||||
bRun = true;
|
||||
|
||||
// main loop of working thread
|
||||
while ( bRun )
|
||||
{
|
||||
// get audio from sound card (blocking function)
|
||||
if ( Sound.Read ( vecsAudioSndCrdStereo ) )
|
||||
{
|
||||
PostWinMessage ( MS_SOUND_IN, MUL_COL_LED_RED );
|
||||
}
|
||||
else
|
||||
{
|
||||
PostWinMessage ( MS_SOUND_IN, MUL_COL_LED_GREEN );
|
||||
}
|
||||
|
||||
// convert data from short to double
|
||||
for ( i = 0; i < iSndCrdStereoBlockSizeSam; i++ )
|
||||
{
|
||||
vecdAudioSndCrdStereo[i] = (double) vecsAudioSndCrdStereo[i];
|
||||
vecdAudioSndCrdStereo[i] = (double) vecsStereoSndCrd[i];
|
||||
}
|
||||
|
||||
// resample data for each channel seaparately
|
||||
|
@ -356,8 +400,8 @@ static FILE* pFileDelay = fopen("v.dat", "wb");
|
|||
short sData[2];
|
||||
for (i = 0; i < iMonoBlockSizeSam; i++)
|
||||
{
|
||||
sData[0] = (short) vecdNetwData[i];
|
||||
fwrite(&sData, size_t(2), size_t(1), pFileDelay);
|
||||
sData[0] = (short) vecdNetwData[i];
|
||||
fwrite(&sData, size_t(2), size_t(1), pFileDelay);
|
||||
}
|
||||
fflush(pFileDelay);
|
||||
*/
|
||||
|
@ -372,49 +416,19 @@ fflush(pFileDelay);
|
|||
// received data in both sound card channels
|
||||
for ( i = 0, j = 0; i < iSndCrdMonoBlockSizeSam; i++, j += 2 )
|
||||
{
|
||||
vecsAudioSndCrdStereo[j] = vecsAudioSndCrdStereo[j + 1] =
|
||||
vecsStereoSndCrd[j] = vecsStereoSndCrd[j + 1] =
|
||||
Double2Short ( vecdAudioSndCrdMono[i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not connected, clear data
|
||||
vecsAudioSndCrdStereo.Reset ( 0 );
|
||||
}
|
||||
|
||||
// play the new block
|
||||
if ( Sound.Write ( vecsAudioSndCrdStereo ) )
|
||||
{
|
||||
PostWinMessage ( MS_SOUND_OUT, MUL_COL_LED_RED );
|
||||
}
|
||||
else
|
||||
{
|
||||
PostWinMessage ( MS_SOUND_OUT, MUL_COL_LED_GREEN );
|
||||
vecsStereoSndCrd.Reset ( 0 );
|
||||
}
|
||||
|
||||
// update response time measurement and socket buffer size
|
||||
UpdateTimeResponseMeasurement();
|
||||
UpdateSocketBufferSize();
|
||||
}
|
||||
|
||||
// disable channel
|
||||
Channel.SetEnable ( false );
|
||||
|
||||
// disable sound interface
|
||||
Sound.Close();
|
||||
|
||||
// reset current signal level and LEDs
|
||||
SignalLevelMeter.Reset();
|
||||
PostWinMessage ( MS_RESET_ALL, 0 );
|
||||
}
|
||||
|
||||
bool CClient::Stop()
|
||||
{
|
||||
// set flag so that thread can leave the main loop
|
||||
bRun = false;
|
||||
|
||||
// give thread some time to terminate, return status
|
||||
return wait ( 5000 );
|
||||
}
|
||||
|
||||
void CClient::UpdateTimeResponseMeasurement()
|
||||
|
|
|
@ -66,8 +66,8 @@ public:
|
|||
CClient ( const quint16 iPortNumber );
|
||||
virtual ~CClient() {}
|
||||
|
||||
void Init();
|
||||
bool Stop();
|
||||
void Start();
|
||||
void Stop();
|
||||
bool IsRunning() { return bRun; }
|
||||
bool SetServerAddr ( QString strNAddr );
|
||||
double MicLevelL() { return SignalLevelMeter.MicLevelLeft(); }
|
||||
|
@ -149,7 +149,9 @@ public:
|
|||
QString strName;
|
||||
|
||||
protected:
|
||||
void Init();
|
||||
virtual void run();
|
||||
void ProcessAudioData ( CVector<short>& vecsStereoSndCrd );
|
||||
void UpdateTimeResponseMeasurement();
|
||||
void UpdateSocketBufferSize();
|
||||
|
||||
|
|
|
@ -267,28 +267,12 @@ void CLlconClientDlg::OnSliderAudInFader ( int value )
|
|||
void CLlconClientDlg::OnConnectDisconBut()
|
||||
{
|
||||
// start/stop client, set button text
|
||||
if ( pClient->IsRunning() )
|
||||
{
|
||||
pClient->Stop();
|
||||
PushButtonConnect->setText ( CON_BUT_CONNECTTEXT );
|
||||
|
||||
// stop timer for level meter bars and reset them
|
||||
TimerSigMet.stop();
|
||||
ProgressBarInputLevelL->setValue ( 0 );
|
||||
ProgressBarInputLevelR->setValue ( 0 );
|
||||
|
||||
// immediately update status bar
|
||||
OnTimerStatus();
|
||||
|
||||
// clear mixer board (remove all faders)
|
||||
MainMixerBoard->HideAll();
|
||||
}
|
||||
else
|
||||
if ( !pClient->IsRunning() )
|
||||
{
|
||||
// set address and check if address is valid
|
||||
if ( pClient->SetServerAddr ( LineEditServerAddr->text() ) )
|
||||
{
|
||||
pClient->start ( QThread::TimeCriticalPriority );
|
||||
pClient->Start();
|
||||
|
||||
PushButtonConnect->setText ( CON_BUT_DISCONNECTTEXT );
|
||||
|
||||
|
@ -305,6 +289,22 @@ void CLlconClientDlg::OnConnectDisconBut()
|
|||
TextLabelStatus->setText ( tr ( "invalid address" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pClient->Stop();
|
||||
PushButtonConnect->setText ( CON_BUT_CONNECTTEXT );
|
||||
|
||||
// stop timer for level meter bars and reset them
|
||||
TimerSigMet.stop();
|
||||
ProgressBarInputLevelL->setValue ( 0 );
|
||||
ProgressBarInputLevelR->setValue ( 0 );
|
||||
|
||||
// immediately update status bar
|
||||
OnTimerStatus();
|
||||
|
||||
// clear mixer board (remove all faders)
|
||||
MainMixerBoard->HideAll();
|
||||
}
|
||||
}
|
||||
|
||||
void CLlconClientDlg::OnOpenGeneralSettings()
|
||||
|
|
Loading…
Reference in a new issue