2 * PROJECT: ReactOS Sound Record Application
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/sndrec32/audio_resampler_acm.cpp
5 * PURPOSE: Audio Resampler
6 * PROGRAMMERS: Marco Pagliaricci <ms_blue (at) hotmail (dot) it>
10 #include "audio_resampler_acm.hpp"
12 _AUDIO_NAMESPACE_START_
15 /////////////////////////////////////////
16 /////// Private Functions ////////
17 /////////////////////////////////////////
21 audio_resampler_acm::init_( void )
30 ZeroMemory( &acm_header
, sizeof( ACMSTREAMHEADER
));
31 ZeroMemory( &wformat_src
, sizeof( WAVEFORMATEX
));
32 ZeroMemory( &wformat_dst
, sizeof( WAVEFORMATEX
));
38 // Setting structures sizes
41 acm_header
.cbStruct
= sizeof( ACMSTREAMHEADER
);
42 wformat_src
.cbSize
= sizeof( WAVEFORMATEX
);
43 wformat_dst
.cbSize
= sizeof( WAVEFORMATEX
);
49 // Setting WAVEFORMATEX structure parameters
50 // according to `audio_format' in/out classes
53 wformat_src
.wFormatTag
= WAVE_FORMAT_PCM
;
54 wformat_src
.nSamplesPerSec
= audfmt_in
.sample_rate();
55 wformat_src
.nChannels
= audfmt_in
.channels();
56 wformat_src
.wBitsPerSample
= audfmt_in
.bits();
57 wformat_src
.nAvgBytesPerSec
= audfmt_in
.byte_rate();
58 wformat_src
.nBlockAlign
= audfmt_in
.block_align();
61 wformat_dst
.wFormatTag
= WAVE_FORMAT_PCM
;
62 wformat_dst
.nSamplesPerSec
= audfmt_out
.sample_rate();
63 wformat_dst
.nChannels
= audfmt_out
.channels();
64 wformat_dst
.wBitsPerSample
= audfmt_out
.bits();
65 wformat_dst
.nAvgBytesPerSec
= audfmt_out
.byte_rate();
66 wformat_dst
.nBlockAlign
= audfmt_out
.block_align();
71 // Init acm structures completed successfull
85 /////////////////////////////////////////
86 /////// Public Functions ////////
87 /////////////////////////////////////////
93 audio_resampler_acm::open( void )
104 err
= acmStreamOpen( &acm_stream
, 0, &wformat_src
, &wformat_dst
,
105 0, 0, 0, ACM_STREAMOPENF_NONREALTIME
);
108 if ( err
!= MMSYSERR_NOERROR
)
111 printf("acmOpen error: %i\n", err
);
118 // Calcs source buffer lenght
121 src_buflen
= ( unsigned int )
122 (( float )audfmt_in
.byte_rate() * ( float )buf_secs
);
130 // Calcs destination source buffer lenght
131 // with help of ACM apis
134 err
= acmStreamSize( acm_stream
,
135 src_buflen
, &dst_buflen
, ACM_STREAMSIZEF_SOURCE
);
138 if ( err
!= MMSYSERR_NOERROR
)
141 printf("acmSize error\n");
148 // Initialize ACMSTREAMHEADER structure,
149 // and alloc memory for source and destination
153 acm_header
.fdwStatus
= 0;
154 acm_header
.dwUser
= 0;
157 acm_header
.pbSrc
= ( LPBYTE
) new BYTE
[ src_buflen
];
158 acm_header
.cbSrcLength
= src_buflen
;
159 acm_header
.cbSrcLengthUsed
= 0;
160 acm_header
.dwSrcUser
= src_buflen
;
163 acm_header
.pbDst
= ( LPBYTE
) new BYTE
[ dst_buflen
];
164 acm_header
.cbDstLength
= dst_buflen
;
165 acm_header
.cbDstLengthUsed
= 0;
166 acm_header
.dwDstUser
= dst_buflen
;
172 // Give ACMSTREAMHEADER initialized correctly to the
176 err
= acmStreamPrepareHeader( acm_stream
, &acm_header
, 0L );
178 if ( err
!= MMSYSERR_NOERROR
)
181 printf("prep. header error\n");
188 // ACM stream successfully opened.
191 stream_opened
= true;
199 audio_resampler_acm::close( void )
209 if ( acm_header
.fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
)
212 acm_header
.cbSrcLength
= src_buflen
;
213 acm_header
.cbDstLength
= dst_buflen
;
215 err
= acmStreamUnprepareHeader( acm_stream
, &acm_header
, 0L );
218 if ( err
!= MMSYSERR_NOERROR
)
222 // Free buffer memory
225 if ( acm_header
.pbSrc
!= 0 )
226 delete[] acm_header
.pbSrc
;
228 if ( acm_header
.pbDst
!= 0 )
229 delete[] acm_header
.pbDst
;
233 // Re-init structures
242 stream_opened
= false;
251 err
= acmStreamClose( acm_stream
, 0 );
254 if ( err
!= MMSYSERR_NOERROR
)
258 // Free buffer memory
261 if ( acm_header
.pbSrc
!= 0 )
262 delete[] acm_header
.pbSrc
;
264 if ( acm_header
.pbDst
!= 0 )
265 delete[] acm_header
.pbDst
;
269 // Re-init structures
279 stream_opened
= false;
287 }//if acm_stream != 0
295 // Free buffer memory
298 if ( acm_header
.pbSrc
!= 0 )
299 delete[] acm_header
.pbSrc
;
301 if ( acm_header
.pbDst
!= 0 )
302 delete[] acm_header
.pbDst
;
306 // Re-init structures
316 stream_opened
= false;
321 // ACM sream successfully closed.
331 audio_resampler_acm::audio_receive( unsigned char * data
, unsigned int size
)
337 // Checking for acm stream opened
345 // Copy audio data from extern to
346 // internal source buffer
349 memcpy( acm_header
.pbSrc
, data
, size
);
352 acm_header
.cbSrcLength
= size
;
353 acm_header
.cbDstLengthUsed
= 0;
355 err
= acmStreamConvert( acm_stream
, &acm_header
, ACM_STREAMCONVERTF_BLOCKALIGN
);
357 if ( err
!= MMSYSERR_NOERROR
)
360 printf("acm convert error\n");
366 // Wait for sound conversion
369 while(( ACMSTREAMHEADER_STATUSF_DONE
& acm_header
.fdwStatus
) == 0 );
372 printf("Processed successfully %lu bytes of audio.\n", acm_header
.cbDstLengthUsed
);
377 // Copy resampled audio, to destination buffer.
380 //memcpy( pbOutputData, acm_header.pbDst, acm_header.cbDstLengthUsed );
387 _AUDIO_NAMESPACE_END_