📄 iocntrl.cpp
字号:
}
if( ErrorCode != NO_ERRORS) //must be some other soundcard error
{
m_pSoundDev->InClose();
ProcessError( ErrorCode );
StopThread();
}
}
}
else //use wave file input
{
if( (ErrorCode=m_pWaveDev->InRead( m_pBuffer, BUF_SIZE )) != BUF_SIZE)
{
m_FFTBufFull = FALSE;
if( ErrorCode < 0)
{
ErrorCode = m_pWaveDev->GetError();
ProcessError( ErrorCode );
}
m_pWaveDev->InClose();
StopThread();
}
Sleep(0);
}
}
//////////////////////////////////////////////////////////////////
// Here with the real input data to process in m_pBuffer
//////////////////////////////////////////////////////////////////
void CIOCntrl::ProcessSimulator()
{
if(m_fProcThreadQuit)
return;
//calculate sum of squares for RMS calculations
for( INT i = 0; i<BUF_SIZE; i++)
{
// SweepGen( &(m_pBuffer[i]), 8000, 10, 4000, 5.0 );
m_SSum = m_SSum + ( m_pBuffer[i]*m_pBuffer[i] );
}
//Simple IIR LP filter the rms averages
m_SigRMS = (1.0/RMSAVE)*sqrt(m_SSum/BUF_SIZE) + (1.0-1.0/RMSAVE)*m_SigRMS;
m_SSum = 0.0;
if(!m_pDoc->m_AWGNOn)
{
m_SignalGain = 1.0;
m_NoiseRMS = 0.0;
}
m_pDoc->m_SigRMS = m_SigRMS;
//
if(!m_pDoc->m_DirectPathActive) //if not direct path
{
//Bandpass filter into I and Q and get delayed versions of the input data
m_pCDelay->CalcBPFilter(m_pBuffer, m_pDelay0Buf );
//double tmp;
// for( i = 0; i<BUF_SIZE; i++)
// {
// tmp = m_pDelay0Buf[i].y;
// CalcSweepRMS(tmp, 10000);
// CalcCpxSweepPhz(m_pDelay0Buf[i],10000);
// }
m_pCDelay->CreateDelays(m_pDelay0Buf, m_pDelay1Buf, m_pDelay2Buf);
//gDebug2 = CalcCpxRunAveRMS(m_pDelay2Buf, BUF_SIZE);
//Calculate each path.
m_pCPath0->CalcPath( m_pDelay0Buf, m_pDelay0Buf );
m_pCPath1->CalcPath( m_pDelay1Buf, m_pDelay1Buf );
m_pCPath2->CalcPath( m_pDelay2Buf, m_pDelay2Buf );
// Sum and Copy just the real part back into the real buffer for output
for( INT i = 0; i<BUF_SIZE; i++)
m_pBuffer[i] = m_pDelay0Buf[i].x + m_pDelay1Buf[i].x + m_pDelay2Buf[i].x;
}
if(m_pDoc->m_AWGNOn) //if AWGN is used, figure out gains for SNR
{
EnterCriticalSection(&m_CriticalSection);
if(m_SNR>=1.0)
{
m_SignalGain = RMS_MAXAMPLITUDE/m_SigRMS;
m_NoiseRMS = (m_SignalGain*m_SigRMS)/m_SNR;
m_pNoiseGen->AddBWLimitedNoise(BUF_SIZE, m_pBuffer, m_SignalGain, m_NoiseRMS);
}
else
{
m_SignalGain = (RMS_MAXAMPLITUDE*m_SNR)/m_SigRMS;
m_NoiseRMS = RMS_MAXAMPLITUDE;
m_pNoiseGen->AddBWLimitedNoise(BUF_SIZE, m_pBuffer, m_SignalGain, RMS_MAXAMPLITUDE);
}
LeaveCriticalSection(&m_CriticalSection);
}
m_pDoc->m_NoiseRMS = m_NoiseRMS;
}
///////////////////////////////////////////////////////////////////////
// Send output data to soundcard or wavefile
///////////////////////////////////////////////////////////////////////
void CIOCntrl::ProcessOutput()
{
BOOL result;
INT ErrorCode;
//gDebug1 = CalcTotalRMS(m_pBuffer, BUF_SIZE);
if(m_fProcThreadQuit)
return;
if( !m_FFTBufFull )
{
if( m_DispCounter <= 0 )
{
EnterCriticalSection(&m_CriticalSection);
m_pCfft->CalcFFT( m_pBuffer );
for(INT i=0; i<BUF_SIZE;i++)
m_pOutputBuf[i] = m_pBuffer[i];
m_FFTBufFull = TRUE;
::PostMessage( m_hWnd, MSG_DATARDY, 0,0) ;
LeaveCriticalSection(&m_CriticalSection);
}
if( m_pDoc->m_WaveToWave ) // if wav to wav, don't display each block
{
if(m_DispCounter-- <= 0)
m_DispCounter = DISPLAY_COUNT_VAL;
}
}
if( m_pDoc->m_OutputSelect == USE_SOUNDCARD )
{
if( (result = m_pSoundDev->OutWrite( m_pBuffer, BUF_SIZE )) != BUF_SIZE)
{
ErrorCode = m_pSoundDev->GetError();
if( (ErrorCode == SOUNDOUT_ERR_UNDERFLOW) ||
(ErrorCode == SOUNDOUT_ERR_TIMEOUT) )
{ //cpu couldn't keep up
// so try again
m_pSoundDev->OutClose();
ErrorCode = m_pSoundDev->OutOpen( &m_OutWaveFormatEx, BUF_SIZE, 0, -1);
}
if( ErrorCode != NO_ERRORS) //must be some other soundcard error
{
m_pSoundDev->OutClose();
ProcessError( ErrorCode );
StopThread();
}
}
}
else
{
if( (ErrorCode=m_pWaveDev->OutWrite( m_pBuffer, BUF_SIZE )) != BUF_SIZE)
{
m_FFTBufFull = FALSE;
if( ErrorCode < 0)
{
ErrorCode = m_pWaveDev->GetError();
ProcessError( ErrorCode );
}
m_pWaveDev->OutClose();
StopThread();
}
m_pDoc->m_SamplesWritten += 2048;
Sleep(0);
}
}
///////////////////////////////////////////////////////////////////////////
// Free resources and exit process thread
// Called by process thread itself to shut itself off if not signaled by
// main program thread.
///////////////////////////////////////////////////////////////////////////
void CIOCntrl::StopThread()
{
m_FFTBufFull = FALSE;
::PostMessage( m_hWnd, MSG_DONE, 0,0);
Sleep(100);
// if any resources are open, kill em.
m_pProcThread->m_bAutoDelete = TRUE; //make thread clean up after
m_pProcThread = NULL; // itself before it dies
DeleteResources();
AfxEndThread(3);
}
///////////////////////////////////////////////////////////////////////////
// Called to delete any allocated resources in this class
///////////////////////////////////////////////////////////////////////////
void CIOCntrl::DeleteResources()
{
m_FFTBufFull = FALSE;
m_ThreadActive = FALSE;
if( m_pSoundDev)
{
m_pSoundDev->InClose();
m_pSoundDev->OutClose();
delete m_pSoundDev;
m_pSoundDev = NULL;
}
if( m_pWaveDev)
{
m_pWaveDev->InClose();
m_pWaveDev->OutClose();
delete m_pWaveDev;
m_pWaveDev = NULL;
}
if(m_pNoiseGen)
{
delete m_pNoiseGen;
m_pNoiseGen = NULL;
}
if(m_pBuffer)
{
delete m_pBuffer;
m_pBuffer = NULL;
}
if(m_pDelay0Buf)
{
delete m_pDelay0Buf;
m_pDelay0Buf = NULL;
}
if(m_pDelay1Buf)
{
delete m_pDelay1Buf;
m_pDelay1Buf = NULL;
}
if(m_pDelay2Buf)
{
delete m_pDelay2Buf;
m_pDelay2Buf = NULL;
}
if(m_pCDelay)
{
delete m_pCDelay;
m_pCDelay = NULL;
}
if( m_pCPath0 )
{
delete m_pCPath0;
m_pCPath0 = NULL;
}
if( m_pCPath1 )
{
delete m_pCPath1;
m_pCPath1 = NULL;
}
if( m_pCPath2 )
{
delete m_pCPath2;
m_pCPath2 = NULL;
}
}
//////////////////////////////////////////////////////////////////////////
// Simple minded error message display for various soundcard errors
// Should be put in string table.
//////////////////////////////////////////////////////////////////////////
void CIOCntrl::ProcessError( INT ErrorCode )
{
switch( ErrorCode )
{
case NO_ERRORS:
m_ErrorMessage = _T("");
break;
case MEMORY_ERROR:
case MMSYSERR_NOMEM:
m_ErrorMessage = _T("Memory Allocation error");
break;
case SOUNDIN_ERR_NOTOPEN:
m_ErrorMessage = _T("Tried to read and soundcard is not open");
break;
case SOUNDIN_ERR_OVERFLOW:
m_ErrorMessage = _T("Input buffers overflowed");
break;
case SOUNDIN_ERR_TIMEOUT:
m_ErrorMessage = _T("Timed out waiting for input buffers");
break;
case SOUNDOUT_ERR_NOTOPEN:
m_ErrorMessage = _T("Tried to write and soundcard is not open");
break;
case SOUNDOUT_ERR_UNDERFLOW:
m_ErrorMessage = _T("Output buffers Underflowed");
break;
case SOUNDOUT_ERR_TIMEOUT:
m_ErrorMessage = _T("Timed out waiting for output buffers");
break;
case WAVERR_BADFORMAT:
m_ErrorMessage = _T("Card doesn't support 16bit, 8000Hz, Mono format");
break;
case WAVERR_STILLPLAYING:
m_ErrorMessage = _T("still something playing");
break;
case WAVERR_UNPREPARED:
m_ErrorMessage = _T("header not prepared ");
break;
case WAVERR_SYNC:
m_ErrorMessage = _T("device is synchronous");
break;
case MMSYSERR_BADDEVICEID:
m_ErrorMessage = _T("Bad Device ID\nIs Soundcard Present?");
break;
case MMSYSERR_NOTENABLED:
m_ErrorMessage = _T("Driver failed enable");
break;
case MMSYSERR_ALLOCATED:
m_ErrorMessage = _T("Device already allocated");
break;
case MMSYSERR_INVALHANDLE:
m_ErrorMessage = _T("Device handle is invalid");
break;
case MMSYSERR_NODRIVER:
m_ErrorMessage = _T("No device driver present");
break;
case MMSYSERR_NOTSUPPORTED:
m_ErrorMessage = _T("Function isn't supported");
break;
case MMSYSERR_BADERRNUM:
m_ErrorMessage = _T("Error value out of range");
break;
case MMSYSERR_INVALFLAG:
m_ErrorMessage = _T("Invalid flag passed");
break;
case MMSYSERR_INVALPARAM:
m_ErrorMessage = _T("Invalid parameter passed");
break;
case MMSYSERR_HANDLEBUSY:
m_ErrorMessage = _T("Handle being used");
break;
case MMSYSERR_NODRIVERCB:
m_ErrorMessage = _T("driver does not call DriverCallback");
break;
case MMSYSERR_INVALIDALIAS:
case MMSYSERR_BADDB:
case MMSYSERR_KEYNOTFOUND:
case MMSYSERR_READERROR:
case MMSYSERR_WRITEERROR:
case MMSYSERR_DELETEERROR:
case MMSYSERR_VALNOTFOUND:
m_ErrorMessage = _T("Registry error");
break;
case WAVIN_ERR_OPEN:
m_ErrorMessage = _T("can't open wave file for input");
break;
case WAVIN_ERR_NOTWAVE:
m_ErrorMessage = _T("file is not a RIFF wave type");
break;
case WAVIN_ERR_INVALID:
m_ErrorMessage = _T("Invalid wave file");
break;
case WAVIN_ERR_NODATA:
m_ErrorMessage = _T("no data in file");
break;
case WAVIN_ERR_NOTSUPPORTED:
m_ErrorMessage = _T("not a supported data type");
break;
case WAVIN_ERR_READING:
m_ErrorMessage = _T("Error reading data from file");
break;
case WAVIN_ERR_NOTOPEN:
m_ErrorMessage = _T("tried to read and file is not open");
break;
case WAVOUT_ERR_OPEN:
m_ErrorMessage = _T("can't open wave file for output");
break;
case WAVOUT_ERR_WRITING:
m_ErrorMessage = _T("error writing to wave file");
break;
case WAVOUT_ERR_NOTOPEN:
m_ErrorMessage = _T("tried to write and file is not open");
break;
default:
m_ErrorMessage = _T("Unknown Error");
break;
}
::PostMessage( m_hWnd, MSG_ERROR, 0,0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -