1159b3361Sopenharmony_ci/**
2159b3361Sopenharmony_ci *
3159b3361Sopenharmony_ci * Lame ACM wrapper, encode/decode MP3 based RIFF/AVI files in MS Windows
4159b3361Sopenharmony_ci *
5159b3361Sopenharmony_ci *  Copyright (c) 2002 Steve Lhomme <steve.lhomme at free.fr>
6159b3361Sopenharmony_ci *
7159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or
8159b3361Sopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either
10159b3361Sopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11159b3361Sopenharmony_ci *
12159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful,
13159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15159b3361Sopenharmony_ci * Lesser General Public License for more details.
16159b3361Sopenharmony_ci *
17159b3361Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18159b3361Sopenharmony_ci * License along with this library; if not, write to the Free Software
19159b3361Sopenharmony_ci * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20159b3361Sopenharmony_ci *
21159b3361Sopenharmony_ci */
22159b3361Sopenharmony_ci
23159b3361Sopenharmony_ci/*!
24159b3361Sopenharmony_ci	\author Steve Lhomme
25159b3361Sopenharmony_ci	\version \$Id$
26159b3361Sopenharmony_ci*/
27159b3361Sopenharmony_ci
28159b3361Sopenharmony_ci#if !defined(STRICT)
29159b3361Sopenharmony_ci#define STRICT
30159b3361Sopenharmony_ci#endif // STRICT
31159b3361Sopenharmony_ci
32159b3361Sopenharmony_ci#include <assert.h>
33159b3361Sopenharmony_ci#include <windows.h>
34159b3361Sopenharmony_ci
35159b3361Sopenharmony_ci#include "adebug.h"
36159b3361Sopenharmony_ci
37159b3361Sopenharmony_ci#include "ACMStream.h"
38159b3361Sopenharmony_ci
39159b3361Sopenharmony_ci#include <lame.h>
40159b3361Sopenharmony_ci
41159b3361Sopenharmony_ci// static methods
42159b3361Sopenharmony_ci
43159b3361Sopenharmony_ciACMStream * ACMStream::Create()
44159b3361Sopenharmony_ci{
45159b3361Sopenharmony_ci	ACMStream * Result;
46159b3361Sopenharmony_ci
47159b3361Sopenharmony_ci	Result = new ACMStream;
48159b3361Sopenharmony_ci
49159b3361Sopenharmony_ci	return Result;
50159b3361Sopenharmony_ci}
51159b3361Sopenharmony_ci
52159b3361Sopenharmony_ciconst bool ACMStream::Erase(const ACMStream * a_ACMStream)
53159b3361Sopenharmony_ci{
54159b3361Sopenharmony_ci	delete a_ACMStream;
55159b3361Sopenharmony_ci	return true;
56159b3361Sopenharmony_ci}
57159b3361Sopenharmony_ci
58159b3361Sopenharmony_ci// class methods
59159b3361Sopenharmony_ci
60159b3361Sopenharmony_ciACMStream::ACMStream() :
61159b3361Sopenharmony_ci m_WorkingBufferUseSize(0),
62159b3361Sopenharmony_ci gfp(NULL)
63159b3361Sopenharmony_ci{
64159b3361Sopenharmony_ci	 /// \todo get the debug level from the registry
65159b3361Sopenharmony_cimy_debug = new ADbg(DEBUG_LEVEL_CREATION);
66159b3361Sopenharmony_ci	if (my_debug != NULL) {
67159b3361Sopenharmony_ci		unsigned char DebugFileName[512];
68159b3361Sopenharmony_ci
69159b3361Sopenharmony_ci		my_debug->setPrefix("LAMEstream"); /// \todo get it from the registry
70159b3361Sopenharmony_cimy_debug->setIncludeTime(true);  /// \todo get it from the registry
71159b3361Sopenharmony_ci
72159b3361Sopenharmony_ci// Check in the registry if we have to Output Debug information
73159b3361Sopenharmony_ciDebugFileName[0] = '\0';
74159b3361Sopenharmony_ci
75159b3361Sopenharmony_ci		HKEY OssKey;
76159b3361Sopenharmony_ci		if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\MUKOLI", 0, KEY_READ , &OssKey ) == ERROR_SUCCESS) {
77159b3361Sopenharmony_ci			DWORD DataType;
78159b3361Sopenharmony_ci			DWORD DebugFileNameSize = 512;
79159b3361Sopenharmony_ci			if (RegQueryValueEx( OssKey, "DebugFile", NULL, &DataType, DebugFileName, &DebugFileNameSize ) == ERROR_SUCCESS) {
80159b3361Sopenharmony_ci				if (DataType == REG_SZ) {
81159b3361Sopenharmony_ci					my_debug->setUseFile(true);
82159b3361Sopenharmony_ci					my_debug->setDebugFile((char *)DebugFileName);
83159b3361Sopenharmony_ci					my_debug->OutPut("Debug file is %s",(char *)DebugFileName);
84159b3361Sopenharmony_ci				}
85159b3361Sopenharmony_ci			}
86159b3361Sopenharmony_ci		}
87159b3361Sopenharmony_ci		my_debug->OutPut(DEBUG_LEVEL_FUNC_START, "ACMStream Creation (0X%08X)",this);
88159b3361Sopenharmony_ci	}
89159b3361Sopenharmony_ci	else {
90159b3361Sopenharmony_ci		ADbg debug;
91159b3361Sopenharmony_ci		debug.OutPut("ACMStream::ACMACMStream : Impossible to create my_debug");
92159b3361Sopenharmony_ci	}
93159b3361Sopenharmony_ci
94159b3361Sopenharmony_ci}
95159b3361Sopenharmony_ci
96159b3361Sopenharmony_ciACMStream::~ACMStream()
97159b3361Sopenharmony_ci{
98159b3361Sopenharmony_ci        // release memory - encoding is finished
99159b3361Sopenharmony_ci	if (gfp) lame_close( gfp );
100159b3361Sopenharmony_ci
101159b3361Sopenharmony_ci	if (my_debug != NULL)
102159b3361Sopenharmony_ci	{
103159b3361Sopenharmony_ci		my_debug->OutPut(DEBUG_LEVEL_FUNC_START, "ACMStream Deletion (0X%08X)",this);
104159b3361Sopenharmony_ci		delete my_debug;
105159b3361Sopenharmony_ci	}
106159b3361Sopenharmony_ci}
107159b3361Sopenharmony_ci
108159b3361Sopenharmony_cibool ACMStream::init(const int nSamplesPerSec, const int nOutputSamplesPerSec, const int nChannels, const int nAvgBytesPerSec, const vbr_mode mode)
109159b3361Sopenharmony_ci{
110159b3361Sopenharmony_ci	bool bResult = false;
111159b3361Sopenharmony_ci
112159b3361Sopenharmony_ci	my_SamplesPerSec  = nSamplesPerSec;
113159b3361Sopenharmony_ci	my_OutBytesPerSec = nOutputSamplesPerSec;
114159b3361Sopenharmony_ci	my_Channels       = nChannels;
115159b3361Sopenharmony_ci	my_AvgBytesPerSec = nAvgBytesPerSec;
116159b3361Sopenharmony_ci	my_VBRMode = mode;
117159b3361Sopenharmony_ci
118159b3361Sopenharmony_ci	bResult = true;
119159b3361Sopenharmony_ci
120159b3361Sopenharmony_ci	return bResult;
121159b3361Sopenharmony_ci
122159b3361Sopenharmony_ci}
123159b3361Sopenharmony_ci
124159b3361Sopenharmony_cibool ACMStream::open(const AEncodeProperties & the_Properties)
125159b3361Sopenharmony_ci{
126159b3361Sopenharmony_ci	bool bResult = false;
127159b3361Sopenharmony_ci
128159b3361Sopenharmony_ci	// Init the MP3 Stream
129159b3361Sopenharmony_ci	// Init the global flags structure
130159b3361Sopenharmony_ci	gfp = lame_init();
131159b3361Sopenharmony_ci
132159b3361Sopenharmony_ci	// Set input sample frequency
133159b3361Sopenharmony_ci	lame_set_in_samplerate( gfp, my_SamplesPerSec );
134159b3361Sopenharmony_ci
135159b3361Sopenharmony_ci	// Set output sample frequency
136159b3361Sopenharmony_ci	lame_set_out_samplerate( gfp, my_OutBytesPerSec );
137159b3361Sopenharmony_ci
138159b3361Sopenharmony_ci	lame_set_num_channels( gfp, my_Channels );
139159b3361Sopenharmony_ci	if (my_Channels == 1)
140159b3361Sopenharmony_ci		lame_set_mode( gfp, MONO );
141159b3361Sopenharmony_ci	else
142159b3361Sopenharmony_ci		lame_set_mode( gfp, (MPEG_mode_e)the_Properties.GetChannelModeValue()) ; /// \todo Get the mode from the default configuration
143159b3361Sopenharmony_ci
144159b3361Sopenharmony_ci//	lame_set_VBR( gfp, vbr_off ); /// \note VBR not supported for the moment
145159b3361Sopenharmony_ci	lame_set_VBR( gfp, my_VBRMode ); /// \note VBR not supported for the moment
146159b3361Sopenharmony_ci
147159b3361Sopenharmony_ci	if (my_VBRMode == vbr_abr)
148159b3361Sopenharmony_ci	{
149159b3361Sopenharmony_ci		lame_set_VBR_q( gfp, 1 );
150159b3361Sopenharmony_ci
151159b3361Sopenharmony_ci		lame_set_VBR_mean_bitrate_kbps( gfp, (my_AvgBytesPerSec * 8 + 500) / 1000 );
152159b3361Sopenharmony_ci
153159b3361Sopenharmony_ci		if (24000 > lame_get_in_samplerate( gfp ))
154159b3361Sopenharmony_ci		{
155159b3361Sopenharmony_ci			// For MPEG-II
156159b3361Sopenharmony_ci			lame_set_VBR_min_bitrate_kbps( gfp, 8);
157159b3361Sopenharmony_ci
158159b3361Sopenharmony_ci			lame_set_VBR_max_bitrate_kbps( gfp, 160);
159159b3361Sopenharmony_ci		}
160159b3361Sopenharmony_ci		else
161159b3361Sopenharmony_ci		{
162159b3361Sopenharmony_ci			// For MPEG-I
163159b3361Sopenharmony_ci			lame_set_VBR_min_bitrate_kbps( gfp, 32);
164159b3361Sopenharmony_ci
165159b3361Sopenharmony_ci			lame_set_VBR_max_bitrate_kbps( gfp, 320);
166159b3361Sopenharmony_ci		}
167159b3361Sopenharmony_ci	}
168159b3361Sopenharmony_ci
169159b3361Sopenharmony_ci	// Set bitrate
170159b3361Sopenharmony_ci	lame_set_brate( gfp, my_AvgBytesPerSec * 8 / 1000 );
171159b3361Sopenharmony_ci
172159b3361Sopenharmony_ci	/// \todo Get the mode from the default configuration
173159b3361Sopenharmony_ci	// Set copyright flag?
174159b3361Sopenharmony_ci	lame_set_copyright( gfp, the_Properties.GetCopyrightMode()?1:0 );
175159b3361Sopenharmony_ci	// Do we have to tag  it as non original
176159b3361Sopenharmony_ci	lame_set_original( gfp, the_Properties.GetOriginalMode()?1:0 );
177159b3361Sopenharmony_ci	// Add CRC?
178159b3361Sopenharmony_ci	lame_set_error_protection( gfp, the_Properties.GetCRCMode()?1:0 );
179159b3361Sopenharmony_ci	// Set private bit?
180159b3361Sopenharmony_ci	lame_set_extension( gfp, the_Properties.GetPrivateMode()?1:0 );
181159b3361Sopenharmony_ci	// INFO tag support not possible in ACM - it requires rewinding
182159b3361Sopenharmony_ci        // output stream to the beginning after encoding is finished.
183159b3361Sopenharmony_ci	lame_set_bWriteVbrTag( gfp, 0 );
184159b3361Sopenharmony_ci
185159b3361Sopenharmony_ci	if (0 == lame_init_params( gfp ))
186159b3361Sopenharmony_ci	{
187159b3361Sopenharmony_ci		//LAME encoding call will accept any number of samples.
188159b3361Sopenharmony_ci		if ( 0 == lame_get_version( gfp ) )
189159b3361Sopenharmony_ci		{
190159b3361Sopenharmony_ci			// For MPEG-II, only 576 samples per frame per channel
191159b3361Sopenharmony_ci			my_SamplesPerBlock = 576 * lame_get_num_channels( gfp );
192159b3361Sopenharmony_ci		}
193159b3361Sopenharmony_ci		else
194159b3361Sopenharmony_ci		{
195159b3361Sopenharmony_ci			// For MPEG-I, 1152 samples per frame per channel
196159b3361Sopenharmony_ci			my_SamplesPerBlock = 1152 * lame_get_num_channels( gfp );
197159b3361Sopenharmony_ci		}
198159b3361Sopenharmony_ci	}
199159b3361Sopenharmony_ci
200159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "version                =%d",lame_get_version( gfp ) );
201159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Layer                  =3");
202159b3361Sopenharmony_ci	switch ( lame_get_mode( gfp ) )
203159b3361Sopenharmony_ci	{
204159b3361Sopenharmony_ci		case STEREO:       my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Stereo" ); break;
205159b3361Sopenharmony_ci		case JOINT_STEREO: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Joint-Stereo" ); break;
206159b3361Sopenharmony_ci		case DUAL_CHANNEL: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Forced Stereo" ); break;
207159b3361Sopenharmony_ci		case MONO:         my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Mono" ); break;
208159b3361Sopenharmony_ci		case NOT_SET:      /* FALLTROUGH */
209159b3361Sopenharmony_ci		default:           my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Error (unknown)" ); break;
210159b3361Sopenharmony_ci	}
211159b3361Sopenharmony_ci
212159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "sampling frequency     =%.1f kHz", lame_get_in_samplerate( gfp ) /1000.0 );
213159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "bitrate                =%d kbps", lame_get_brate( gfp ) );
214159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Vbr Min bitrate        =%d kbps", lame_get_VBR_min_bitrate_kbps( gfp ) );
215159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Vbr Max bitrate        =%d kbps", lame_get_VBR_max_bitrate_kbps( gfp ) );
216159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Quality Setting        =%d", lame_get_quality( gfp ) );
217159b3361Sopenharmony_ci
218159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Low pass frequency     =%d", lame_get_lowpassfreq( gfp ) );
219159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Low pass width         =%d", lame_get_lowpasswidth( gfp ) );
220159b3361Sopenharmony_ci
221159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "High pass frequency    =%d", lame_get_highpassfreq( gfp ) );
222159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "High pass width        =%d", lame_get_highpasswidth( gfp ) );
223159b3361Sopenharmony_ci
224159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "No Short Blocks        =%d", lame_get_no_short_blocks( gfp ) );
225159b3361Sopenharmony_ci
226159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "de-emphasis            =%d", lame_get_emphasis( gfp ) );
227159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "private flag           =%d", lame_get_extension( gfp ) );
228159b3361Sopenharmony_ci
229159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "copyright flag         =%d", lame_get_copyright( gfp ) );
230159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "original flag          =%d",	lame_get_original( gfp ) );
231159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "CRC                    =%s", lame_get_error_protection( gfp ) ? "on" : "off" );
232159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Fast mode              =%s", ( lame_get_quality( gfp ) )? "enabled" : "disabled" );
233159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Force mid/side stereo  =%s", ( lame_get_force_ms( gfp ) )?"enabled":"disabled" );
234159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Disable Resorvoir      =%d", lame_get_disable_reservoir( gfp ) );
235159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "VBR                    =%s, VBR_q =%d, VBR method =",
236159b3361Sopenharmony_ci					( lame_get_VBR( gfp ) !=vbr_off ) ? "enabled": "disabled",
237159b3361Sopenharmony_ci		            lame_get_VBR_q( gfp ) );
238159b3361Sopenharmony_ci
239159b3361Sopenharmony_ci	switch ( lame_get_VBR( gfp ) )
240159b3361Sopenharmony_ci	{
241159b3361Sopenharmony_ci		case vbr_off:	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_off" );	break;
242159b3361Sopenharmony_ci		case vbr_mt :	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_mt" );	break;
243159b3361Sopenharmony_ci		case vbr_rh :	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_rh" );	break;
244159b3361Sopenharmony_ci		case vbr_mtrh:	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_mtrh" );	break;
245159b3361Sopenharmony_ci		case vbr_abr:
246159b3361Sopenharmony_ci			my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_abr (average bitrate %d kbps)", lame_get_VBR_mean_bitrate_kbps( gfp ) );
247159b3361Sopenharmony_ci		break;
248159b3361Sopenharmony_ci		default:
249159b3361Sopenharmony_ci			my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "error, unknown VBR setting");
250159b3361Sopenharmony_ci		break;
251159b3361Sopenharmony_ci	}
252159b3361Sopenharmony_ci
253159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Write VBR Header       =%s\n", ( lame_get_bWriteVbrTag( gfp ) ) ?"Yes":"No");
254159b3361Sopenharmony_ci
255159b3361Sopenharmony_ci#ifdef FROM_DLL
256159b3361Sopenharmony_cibeConfig.format.LHV1.dwReSampleRate		= my_OutBytesPerSec;	  // force the user resampling
257159b3361Sopenharmony_ci#endif // FROM_DLL
258159b3361Sopenharmony_ci
259159b3361Sopenharmony_ci	bResult = true;
260159b3361Sopenharmony_ci
261159b3361Sopenharmony_ci	return bResult;
262159b3361Sopenharmony_ci}
263159b3361Sopenharmony_ci
264159b3361Sopenharmony_cibool ACMStream::close(LPBYTE pOutputBuffer, DWORD *pOutputSize)
265159b3361Sopenharmony_ci{
266159b3361Sopenharmony_ci
267159b3361Sopenharmony_cibool bResult = false;
268159b3361Sopenharmony_ci
269159b3361Sopenharmony_ci	int nOutputSamples = 0;
270159b3361Sopenharmony_ci
271159b3361Sopenharmony_ci    nOutputSamples = lame_encode_flush( gfp, pOutputBuffer, 0 );
272159b3361Sopenharmony_ci
273159b3361Sopenharmony_ci	if ( nOutputSamples < 0 )
274159b3361Sopenharmony_ci	{
275159b3361Sopenharmony_ci		// BUFFER_TOO_SMALL
276159b3361Sopenharmony_ci*pOutputSize = 0;
277159b3361Sopenharmony_ci	}
278159b3361Sopenharmony_ci	else
279159b3361Sopenharmony_ci{
280159b3361Sopenharmony_ci		*pOutputSize = nOutputSamples;
281159b3361Sopenharmony_ci
282159b3361Sopenharmony_ci		bResult = true;
283159b3361Sopenharmony_ci	}
284159b3361Sopenharmony_ci
285159b3361Sopenharmony_ci	// lame will be closed in destructor
286159b3361Sopenharmony_ci        //lame_close( gfp );
287159b3361Sopenharmony_ci
288159b3361Sopenharmony_ci	return bResult;
289159b3361Sopenharmony_ci}
290159b3361Sopenharmony_ci
291159b3361Sopenharmony_ciDWORD ACMStream::GetOutputSizeForInput(const DWORD the_SrcLength) const
292159b3361Sopenharmony_ci{
293159b3361Sopenharmony_ci/*	double OutputInputRatio;
294159b3361Sopenharmony_ci
295159b3361Sopenharmony_ci	if (my_VBRMode == vbr_off)
296159b3361Sopenharmony_ci		OutputInputRatio = double(my_AvgBytesPerSec) / double(my_OutBytesPerSec * 2);
297159b3361Sopenharmony_ci	else // reserve the space for 320 kbps
298159b3361Sopenharmony_ci		OutputInputRatio = 40000.0 / double(my_OutBytesPerSec * 2);
299159b3361Sopenharmony_ci
300159b3361Sopenharmony_ci	OutputInputRatio *= 1.15; // allow 15% more*/
301159b3361Sopenharmony_ci
302159b3361Sopenharmony_ci    DWORD Result;
303159b3361Sopenharmony_ci
304159b3361Sopenharmony_ci//	Result = DWORD(double(the_SrcLength) * OutputInputRatio);
305159b3361Sopenharmony_ci    Result = DWORD(1.25*the_SrcLength + 7200);
306159b3361Sopenharmony_ci
307159b3361Sopenharmony_cimy_debug->OutPut(DEBUG_LEVEL_FUNC_CODE, "Result = %d",Result);
308159b3361Sopenharmony_ci
309159b3361Sopenharmony_ci	return Result;
310159b3361Sopenharmony_ci}
311159b3361Sopenharmony_ci
312159b3361Sopenharmony_cibool ACMStream::ConvertBuffer(LPACMDRVSTREAMHEADER a_StreamHeader)
313159b3361Sopenharmony_ci{
314159b3361Sopenharmony_ci	bool result;
315159b3361Sopenharmony_ci
316159b3361Sopenharmony_ciif (my_debug != NULL)
317159b3361Sopenharmony_ci{
318159b3361Sopenharmony_cimy_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "enter ACMStream::ConvertBuffer");
319159b3361Sopenharmony_ci}
320159b3361Sopenharmony_ci
321159b3361Sopenharmony_ci	DWORD InSize = a_StreamHeader->cbSrcLength / 2, OutSize = a_StreamHeader->cbDstLength; // 2 for 8<->16 bits
322159b3361Sopenharmony_ci
323159b3361Sopenharmony_ci// Encode it
324159b3361Sopenharmony_ciint dwSamples;
325159b3361Sopenharmony_ci	int nOutputSamples = 0;
326159b3361Sopenharmony_ci
327159b3361Sopenharmony_ci	dwSamples = InSize / lame_get_num_channels( gfp );
328159b3361Sopenharmony_ci
329159b3361Sopenharmony_ci	if ( 1 == lame_get_num_channels( gfp ) )
330159b3361Sopenharmony_ci	{
331159b3361Sopenharmony_ci		nOutputSamples = lame_encode_buffer(gfp,(PSHORT)a_StreamHeader->pbSrc,(PSHORT)a_StreamHeader->pbSrc,dwSamples,a_StreamHeader->pbDst,a_StreamHeader->cbDstLength);
332159b3361Sopenharmony_ci	}
333159b3361Sopenharmony_ci	else
334159b3361Sopenharmony_ci	{
335159b3361Sopenharmony_ci		nOutputSamples = lame_encode_buffer_interleaved(gfp,(PSHORT)a_StreamHeader->pbSrc,dwSamples,a_StreamHeader->pbDst,a_StreamHeader->cbDstLength);
336159b3361Sopenharmony_ci	}
337159b3361Sopenharmony_ci
338159b3361Sopenharmony_ci	a_StreamHeader->cbSrcLengthUsed = a_StreamHeader->cbSrcLength;
339159b3361Sopenharmony_ci	a_StreamHeader->cbDstLengthUsed = nOutputSamples;
340159b3361Sopenharmony_ci
341159b3361Sopenharmony_ci	result = a_StreamHeader->cbDstLengthUsed <= a_StreamHeader->cbDstLength;
342159b3361Sopenharmony_ci
343159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_CODE, "UsedSize = %d / EncodedSize = %d, result = %d (%d <= %d)", InSize, OutSize, result, a_StreamHeader->cbDstLengthUsed, a_StreamHeader->cbDstLength);
344159b3361Sopenharmony_ci
345159b3361Sopenharmony_ciif (my_debug != NULL)
346159b3361Sopenharmony_ci{
347159b3361Sopenharmony_cimy_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "ACMStream::ConvertBuffer result = %d (0x%02X 0x%02X)",result,a_StreamHeader->pbDst[0],a_StreamHeader->pbDst[1]);
348159b3361Sopenharmony_ci}
349159b3361Sopenharmony_ci
350159b3361Sopenharmony_ci	return result;
351159b3361Sopenharmony_ci}
352159b3361Sopenharmony_ci
353159b3361Sopenharmony_ci/* map frequency to a valid MP3 sample frequency
354159b3361Sopenharmony_ci *
355159b3361Sopenharmony_ci * Robert Hegemann 2000-07-01
356159b3361Sopenharmony_ci */
357159b3361Sopenharmony_cistatic int
358159b3361Sopenharmony_cimap2MP3Frequency(int freq)
359159b3361Sopenharmony_ci{
360159b3361Sopenharmony_ci    if (freq <= 8000)
361159b3361Sopenharmony_ci        return 8000;
362159b3361Sopenharmony_ci    if (freq <= 11025)
363159b3361Sopenharmony_ci        return 11025;
364159b3361Sopenharmony_ci    if (freq <= 12000)
365159b3361Sopenharmony_ci        return 12000;
366159b3361Sopenharmony_ci    if (freq <= 16000)
367159b3361Sopenharmony_ci        return 16000;
368159b3361Sopenharmony_ci    if (freq <= 22050)
369159b3361Sopenharmony_ci        return 22050;
370159b3361Sopenharmony_ci    if (freq <= 24000)
371159b3361Sopenharmony_ci        return 24000;
372159b3361Sopenharmony_ci    if (freq <= 32000)
373159b3361Sopenharmony_ci        return 32000;
374159b3361Sopenharmony_ci    if (freq <= 44100)
375159b3361Sopenharmony_ci        return 44100;
376159b3361Sopenharmony_ci
377159b3361Sopenharmony_ci    return 48000;
378159b3361Sopenharmony_ci}
379159b3361Sopenharmony_ci
380159b3361Sopenharmony_ci
381159b3361Sopenharmony_ciunsigned int ACMStream::GetOutputSampleRate(int samples_per_sec, int bitrate, int channels)
382159b3361Sopenharmony_ci{
383159b3361Sopenharmony_ci    if (bitrate==0)
384159b3361Sopenharmony_ci        bitrate = (64000*channels)/8;
385159b3361Sopenharmony_ci
386159b3361Sopenharmony_ci        /// \todo pass through the same LAME routine
387159b3361Sopenharmony_ci	unsigned int OutputFrequency;
388159b3361Sopenharmony_ci	double compression_ratio = double(samples_per_sec * 16 * channels / (bitrate * 8));
389159b3361Sopenharmony_ci	if (compression_ratio > 13.)
390159b3361Sopenharmony_ci		OutputFrequency = map2MP3Frequency( (10. * bitrate * 8) / (16 * channels));
391159b3361Sopenharmony_ci	else
392159b3361Sopenharmony_ci		OutputFrequency = map2MP3Frequency( 0.97 * samples_per_sec );
393159b3361Sopenharmony_ci
394159b3361Sopenharmony_ci	return OutputFrequency;
395159b3361Sopenharmony_ci
396159b3361Sopenharmony_ci}
397159b3361Sopenharmony_ci
398