/* PROJECT: ReactOS sndrec32 * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/sndrec32/audio_resampler_acm.cpp * PURPOSE: Sound recording * PROGRAMMERS: Marco Pagliaricci (irc: rendar) */ #include "stdafx.h" #include "audio_resampler_acm.hpp" #include _AUDIO_NAMESPACE_START_ ///////////////////////////////////////// /////// Private Functions //////// ///////////////////////////////////////// void audio_resampler_acm::init_( void ) { // // Zeroing structures // ZeroMemory( &acm_header, sizeof( ACMSTREAMHEADER )); ZeroMemory( &wformat_src, sizeof( WAVEFORMATEX )); ZeroMemory( &wformat_dst, sizeof( WAVEFORMATEX )); // // Setting structures sizes // acm_header.cbStruct = sizeof( ACMSTREAMHEADER ); wformat_src.cbSize = sizeof( WAVEFORMATEX ); wformat_dst.cbSize = sizeof( WAVEFORMATEX ); // // Setting WAVEFORMATEX structure parameters // according to `audio_format' in/out classes // wformat_src.wFormatTag = WAVE_FORMAT_PCM; wformat_src.nSamplesPerSec = audfmt_in.sample_rate(); wformat_src.nChannels = audfmt_in.channels(); wformat_src.wBitsPerSample = audfmt_in.bits(); wformat_src.nAvgBytesPerSec = audfmt_in.byte_rate(); wformat_src.nBlockAlign = audfmt_in.block_align(); wformat_dst.wFormatTag = WAVE_FORMAT_PCM; wformat_dst.nSamplesPerSec = audfmt_out.sample_rate(); wformat_dst.nChannels = audfmt_out.channels(); wformat_dst.wBitsPerSample = audfmt_out.bits(); wformat_dst.nAvgBytesPerSec = audfmt_out.byte_rate(); wformat_dst.nBlockAlign = audfmt_out.block_align(); // // Init acm structures completed successfull // } ///////////////////////////////////////// /////// Public Functions //////// ///////////////////////////////////////// void audio_resampler_acm::open( void ) { MMRESULT err; // // Opens ACM stream // err = acmStreamOpen( &acm_stream, 0, &wformat_src, &wformat_dst, 0, 0, 0, ACM_STREAMOPENF_NONREALTIME ); if ( err != MMSYSERR_NOERROR ) { //TODO: throw error MessageBox( 0, _T("acmOpen error: %i"), _T("ERROR"), MB_ICONERROR ); } // // Calcs source buffer lenght // src_buflen = ( unsigned int ) (( float )audfmt_in.byte_rate() * ( float )buf_secs ); // // Calcs destination source buffer lenght // with help of ACM apis // err = acmStreamSize( acm_stream, src_buflen, &dst_buflen, ACM_STREAMSIZEF_SOURCE ); if ( err != MMSYSERR_NOERROR ) { //TODO: throw error MessageBox( 0, _T("acmStreamSize error"), _T("ERROR"), MB_ICONERROR ); } // // Initialize ACMSTREAMHEADER structure, // and alloc memory for source and destination // buffers. // acm_header.fdwStatus = 0; acm_header.dwUser = 0; acm_header.pbSrc = ( LPBYTE ) new BYTE [ src_buflen ]; acm_header.cbSrcLength = src_buflen; acm_header.cbSrcLengthUsed = 0; acm_header.dwSrcUser = src_buflen; acm_header.pbDst = ( LPBYTE ) new BYTE [ dst_buflen ]; acm_header.cbDstLength = dst_buflen; acm_header.cbDstLengthUsed = 0; acm_header.dwDstUser = dst_buflen; // // Give ACMSTREAMHEADER initialized correctly to the // driver. // err = acmStreamPrepareHeader( acm_stream, &acm_header, 0L ); if ( err != MMSYSERR_NOERROR ) { //TODO: throw error MessageBox( 0, _T("acmStreamPrepareHeader error"), _T("ERROR"), MB_ICONERROR ); } // // ACM stream successfully opened. // stream_opened = true; } void audio_resampler_acm::close( void ) { MMRESULT err; if ( acm_stream ) { if ( acm_header.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED ) { acm_header.cbSrcLength = src_buflen; acm_header.cbDstLength = dst_buflen; err = acmStreamUnprepareHeader( acm_stream, &acm_header, 0L ); if ( err != MMSYSERR_NOERROR ) { // // Free buffer memory // if ( acm_header.pbSrc != 0 ) delete[] acm_header.pbSrc; if ( acm_header.pbDst != 0 ) delete[] acm_header.pbDst; // // Re-init structures // init_(); // // Updating status // stream_opened = false; //TODO: throw error MessageBox( 0, _T("acmStreamUnPrepareHeader error"), _T("ERROR"), MB_ICONERROR ); } } err = acmStreamClose( acm_stream, 0 ); acm_stream = 0; if ( err != MMSYSERR_NOERROR ) { // // Free buffer memory // if ( acm_header.pbSrc != 0 ) delete[] acm_header.pbSrc; if ( acm_header.pbDst != 0 ) delete[] acm_header.pbDst; // // Re-init structures // init_(); // // Updating status // stream_opened = false; //TODO: throw error! MessageBox( 0, _T("acmStreamClose error"), _T("ERROR"), MB_ICONERROR ); } }//if acm_stream != 0 // // Free buffer memory // if ( acm_header.pbSrc != 0 ) delete[] acm_header.pbSrc; if ( acm_header.pbDst != 0 ) delete[] acm_header.pbDst; // // Re-init structures // init_(); // // Updating status // stream_opened = false; // // ACM sream successfully closed. // } void audio_resampler_acm::audio_receive( unsigned char * data, unsigned int size ) { MMRESULT err; // // Checking for acm stream opened // if ( stream_opened ) { // // Copy audio data from extern to // internal source buffer // memcpy( acm_header.pbSrc, data, size ); acm_header.cbSrcLength = size; acm_header.cbDstLengthUsed = 0; err = acmStreamConvert( acm_stream, &acm_header, ACM_STREAMCONVERTF_BLOCKALIGN ); if ( err != MMSYSERR_NOERROR ) { //TODO: throw error MessageBox( 0, _T("acmStreamConvert error"), _T("ERROR"), MB_ICONERROR ); } // // Wait for sound conversion // while(( ACMSTREAMHEADER_STATUSF_DONE & acm_header.fdwStatus ) == 0 ); // // Copy resampled audio, to destination buffer. // //memcpy( pbOutputData, acm_header.pbDst, acm_header.cbDstLengthUsed ); } } _AUDIO_NAMESPACE_END_