⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iocntrl.cpp

📁 信道仿真源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			}
			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 + -