1 /* PROJECT: ReactOS sndrec32
2 * LICENSE: GPL - See COPYING in the top level directory
3 * FILE: base/applications/sndrec32/audio_resampler_acm.cpp
4 * PURPOSE: Sound recording
5 * PROGRAMMERS: Marco Pagliaricci (irc: rendar)
10 #include "audio_resampler_acm.hpp"
15 _AUDIO_NAMESPACE_START_
18 /////////////////////////////////////////
19 /////// Private Functions ////////
20 /////////////////////////////////////////
24 audio_resampler_acm::init_( void )
33 ZeroMemory( &acm_header
, sizeof( ACMSTREAMHEADER
));
34 ZeroMemory( &wformat_src
, sizeof( WAVEFORMATEX
));
35 ZeroMemory( &wformat_dst
, sizeof( WAVEFORMATEX
));
41 // Setting structures sizes
44 acm_header
.cbStruct
= sizeof( ACMSTREAMHEADER
);
45 wformat_src
.cbSize
= sizeof( WAVEFORMATEX
);
46 wformat_dst
.cbSize
= sizeof( WAVEFORMATEX
);
52 // Setting WAVEFORMATEX structure parameters
53 // according to `audio_format' in/out classes
56 wformat_src
.wFormatTag
= WAVE_FORMAT_PCM
;
57 wformat_src
.nSamplesPerSec
= audfmt_in
.sample_rate();
58 wformat_src
.nChannels
= audfmt_in
.channels();
59 wformat_src
.wBitsPerSample
= audfmt_in
.bits();
60 wformat_src
.nAvgBytesPerSec
= audfmt_in
.byte_rate();
61 wformat_src
.nBlockAlign
= audfmt_in
.block_align();
64 wformat_dst
.wFormatTag
= WAVE_FORMAT_PCM
;
65 wformat_dst
.nSamplesPerSec
= audfmt_out
.sample_rate();
66 wformat_dst
.nChannels
= audfmt_out
.channels();
67 wformat_dst
.wBitsPerSample
= audfmt_out
.bits();
68 wformat_dst
.nAvgBytesPerSec
= audfmt_out
.byte_rate();
69 wformat_dst
.nBlockAlign
= audfmt_out
.block_align();
74 // Init acm structures completed successfull
88 /////////////////////////////////////////
89 /////// Public Functions ////////
90 /////////////////////////////////////////
96 audio_resampler_acm::open( void )
107 err
= acmStreamOpen( &acm_stream
, 0, &wformat_src
, &wformat_dst
,
108 0, 0, 0, ACM_STREAMOPENF_NONREALTIME
);
111 if ( err
!= MMSYSERR_NOERROR
)
114 MessageBox( 0, _T("acmOpen error: %i"), _T("ERROR"), MB_ICONERROR
);
121 // Calcs source buffer length
124 src_buflen
= ( unsigned int )
125 (( float )audfmt_in
.byte_rate() * ( float )buf_secs
);
133 // Calcs destination source buffer length
134 // with help of ACM apis
137 err
= acmStreamSize( acm_stream
,
138 src_buflen
, &dst_buflen
, ACM_STREAMSIZEF_SOURCE
);
141 if ( err
!= MMSYSERR_NOERROR
)
144 MessageBox( 0, _T("acmStreamSize error"), _T("ERROR"), MB_ICONERROR
);
152 // Initialize ACMSTREAMHEADER structure,
153 // and alloc memory for source and destination
157 acm_header
.fdwStatus
= 0;
158 acm_header
.dwUser
= 0;
161 acm_header
.pbSrc
= ( LPBYTE
) new BYTE
[ src_buflen
];
162 acm_header
.cbSrcLength
= src_buflen
;
163 acm_header
.cbSrcLengthUsed
= 0;
164 acm_header
.dwSrcUser
= src_buflen
;
167 acm_header
.pbDst
= ( LPBYTE
) new BYTE
[ dst_buflen
];
168 acm_header
.cbDstLength
= dst_buflen
;
169 acm_header
.cbDstLengthUsed
= 0;
170 acm_header
.dwDstUser
= dst_buflen
;
176 // Give ACMSTREAMHEADER initialized correctly to the
180 err
= acmStreamPrepareHeader( acm_stream
, &acm_header
, 0L );
182 if ( err
!= MMSYSERR_NOERROR
)
185 MessageBox( 0, _T("acmStreamPrepareHeader error"), _T("ERROR"), MB_ICONERROR
);
194 // ACM stream successfully opened.
197 stream_opened
= true;
205 audio_resampler_acm::close( void )
215 if ( acm_header
.fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
)
218 acm_header
.cbSrcLength
= src_buflen
;
219 acm_header
.cbDstLength
= dst_buflen
;
221 err
= acmStreamUnprepareHeader( acm_stream
, &acm_header
, 0L );
224 if ( err
!= MMSYSERR_NOERROR
)
228 // Free buffer memory
231 if ( acm_header
.pbSrc
!= 0 )
232 delete[] acm_header
.pbSrc
;
234 if ( acm_header
.pbDst
!= 0 )
235 delete[] acm_header
.pbDst
;
239 // Re-init structures
248 stream_opened
= false;
252 MessageBox( 0, _T("acmStreamUnPrepareHeader error"), _T("ERROR"), MB_ICONERROR
);
259 err
= acmStreamClose( acm_stream
, 0 );
262 if ( err
!= MMSYSERR_NOERROR
)
266 // Free buffer memory
269 if ( acm_header
.pbSrc
!= 0 )
270 delete[] acm_header
.pbSrc
;
272 if ( acm_header
.pbDst
!= 0 )
273 delete[] acm_header
.pbDst
;
277 // Re-init structures
287 stream_opened
= false;
292 MessageBox( 0, _T("acmStreamClose error"), _T("ERROR"), MB_ICONERROR
);
298 }//if acm_stream != 0
306 // Free buffer memory
309 if ( acm_header
.pbSrc
!= 0 )
310 delete[] acm_header
.pbSrc
;
312 if ( acm_header
.pbDst
!= 0 )
313 delete[] acm_header
.pbDst
;
317 // Re-init structures
327 stream_opened
= false;
332 // ACM sream successfully closed.
342 audio_resampler_acm::audio_receive( unsigned char * data
, unsigned int size
)
348 // Checking for acm stream opened
356 // Copy audio data from extern to
357 // internal source buffer
360 memcpy( acm_header
.pbSrc
, data
, size
);
363 acm_header
.cbSrcLength
= size
;
364 acm_header
.cbDstLengthUsed
= 0;
366 err
= acmStreamConvert( acm_stream
, &acm_header
, ACM_STREAMCONVERTF_BLOCKALIGN
);
368 if ( err
!= MMSYSERR_NOERROR
)
371 MessageBox( 0, _T("acmStreamConvert error"), _T("ERROR"), MB_ICONERROR
);
378 // Wait for sound conversion
381 while(( ACMSTREAMHEADER_STATUSF_DONE
& acm_header
.fdwStatus
) == 0 );
388 // Copy resampled audio, to destination buffer.
391 //memcpy( pbOutputData, acm_header.pbDst, acm_header.cbDstLengthUsed );
407 _AUDIO_NAMESPACE_END_