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)
9 #include "audio_resampler_acm.hpp"
11 _AUDIO_NAMESPACE_START_
13 /* Private Functions */
16 audio_resampler_acm::init_(void)
18 /* Zeroing structures */
19 ZeroMemory(&acm_header
, sizeof(ACMSTREAMHEADER
));
20 ZeroMemory(&wformat_src
, sizeof(WAVEFORMATEX
));
21 ZeroMemory(&wformat_dst
, sizeof(WAVEFORMATEX
));
23 /* Setting structures sizes */
24 acm_header
.cbStruct
= sizeof(ACMSTREAMHEADER
);
25 wformat_src
.cbSize
= sizeof(WAVEFORMATEX
);
26 wformat_dst
.cbSize
= sizeof(WAVEFORMATEX
);
28 /* Setting WAVEFORMATEX structure parameters
29 according to `audio_format' in/out classes */
31 wformat_src
.wFormatTag
= WAVE_FORMAT_PCM
;
32 wformat_src
.nSamplesPerSec
= audfmt_in
.sample_rate();
33 wformat_src
.nChannels
= audfmt_in
.channels();
34 wformat_src
.wBitsPerSample
= audfmt_in
.bits();
35 wformat_src
.nAvgBytesPerSec
= audfmt_in
.byte_rate();
36 wformat_src
.nBlockAlign
= audfmt_in
.block_align();
38 wformat_dst
.wFormatTag
= WAVE_FORMAT_PCM
;
39 wformat_dst
.nSamplesPerSec
= audfmt_out
.sample_rate();
40 wformat_dst
.nChannels
= audfmt_out
.channels();
41 wformat_dst
.wBitsPerSample
= audfmt_out
.bits();
42 wformat_dst
.nAvgBytesPerSec
= audfmt_out
.byte_rate();
43 wformat_dst
.nBlockAlign
= audfmt_out
.block_align();
45 /* Init acm structures completed successful */
48 /* Public Functions */
51 audio_resampler_acm::open(void)
55 /* Opens ACM stream */
56 err
= acmStreamOpen(&acm_stream
,
61 ACM_STREAMOPENF_NONREALTIME
);
63 if (err
!= MMSYSERR_NOERROR
)
65 /* TODO: throw error */
66 MessageBox(0, _T("acmOpen error: %i"), _T("ERROR"), MB_ICONERROR
);
69 /* Calcs source buffer length */
70 src_buflen
= (unsigned int)((float)audfmt_in
.byte_rate() * (float)buf_secs
);
72 /* Calcs destination source buffer length with help of ACM apis */
73 err
= acmStreamSize(acm_stream
,
76 ACM_STREAMSIZEF_SOURCE
);
78 if (err
!= MMSYSERR_NOERROR
)
80 /* TODO: throw error */
81 MessageBox(0, _T("acmStreamSize error"), _T("ERROR"), MB_ICONERROR
);
84 /* Initialize ACMSTREAMHEADER structure,
85 and alloc memory for source and destination buffers */
87 acm_header
.fdwStatus
= 0;
88 acm_header
.dwUser
= 0;
90 acm_header
.pbSrc
= (LPBYTE
) new BYTE
[src_buflen
];
91 acm_header
.cbSrcLength
= src_buflen
;
92 acm_header
.cbSrcLengthUsed
= 0;
93 acm_header
.dwSrcUser
= src_buflen
;
95 acm_header
.pbDst
= (LPBYTE
) new BYTE
[dst_buflen
];
96 acm_header
.cbDstLength
= dst_buflen
;
97 acm_header
.cbDstLengthUsed
= 0;
98 acm_header
.dwDstUser
= dst_buflen
;
100 /* Give ACMSTREAMHEADER initialized correctly to the driver */
101 err
= acmStreamPrepareHeader(acm_stream
, &acm_header
, 0L);
102 if (err
!= MMSYSERR_NOERROR
)
104 /* TODO: throw error */
105 MessageBox(0, _T("acmStreamPrepareHeader error"), _T("ERROR"), MB_ICONERROR
);
108 /* ACM stream successfully opened */
109 stream_opened
= true;
113 audio_resampler_acm::close(void)
119 if (acm_header
.fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
)
121 acm_header
.cbSrcLength
= src_buflen
;
122 acm_header
.cbDstLength
= dst_buflen
;
124 err
= acmStreamUnprepareHeader(acm_stream
, &acm_header
, 0L);
125 if (err
!= MMSYSERR_NOERROR
)
127 /* Free buffer memory */
128 if (acm_header
.pbSrc
!= 0)
129 delete[] acm_header
.pbSrc
;
131 if (acm_header
.pbDst
!= 0)
132 delete[] acm_header
.pbDst
;
134 /* Re-init structures */
136 /* Updating status */
137 stream_opened
= false;
138 /* TODO: throw error */
139 MessageBox(0, _T("acmStreamUnPrepareHeader error"), _T("ERROR"), MB_ICONERROR
);
143 err
= acmStreamClose(acm_stream
, 0);
146 if (err
!= MMSYSERR_NOERROR
)
148 /* Free buffer memory */
149 if (acm_header
.pbSrc
!= 0)
150 delete[] acm_header
.pbSrc
;
152 if (acm_header
.pbDst
!= 0)
153 delete[] acm_header
.pbDst
;
155 /* Re-init structures */
157 /* Updating status */
158 stream_opened
= false;
159 /* TODO: throw error! */
160 MessageBox(0, _T("acmStreamClose error"), _T("ERROR"), MB_ICONERROR
);
163 } /* if acm_stream != 0 */
165 /* Free buffer memory */
166 if (acm_header
.pbSrc
!= 0)
167 delete[] acm_header
.pbSrc
;
169 if (acm_header
.pbDst
!= 0)
170 delete[] acm_header
.pbDst
;
172 /* Re-init structures */
174 /* Updating status */
175 stream_opened
= false;
177 /* ACM sream successfully closed */
181 audio_resampler_acm::audio_receive(unsigned char *data
, unsigned int size
)
185 /* Checking for acm stream opened */
188 /* Copy audio data from extern to internal source buffer */
189 memcpy(acm_header
.pbSrc
, data
, size
);
191 acm_header
.cbSrcLength
= size
;
192 acm_header
.cbDstLengthUsed
= 0;
194 err
= acmStreamConvert(acm_stream
, &acm_header
, ACM_STREAMCONVERTF_BLOCKALIGN
);
196 if (err
!= MMSYSERR_NOERROR
)
198 /* TODO: throw error */
199 MessageBox(0, _T("acmStreamConvert error"), _T("ERROR"), MB_ICONERROR
);
202 /* Wait for sound conversion */
203 while ((ACMSTREAMHEADER_STATUSF_DONE
& acm_header
.fdwStatus
) == 0);
205 /* Copy resampled audio, to destination buffer */
206 //memcpy(pbOutputData, acm_header.pbDst, acm_header.cbDstLengthUsed);
210 _AUDIO_NAMESPACE_END_