xref: /third_party/lame/ACM/DecodeStream.cpp (revision 159b3361)
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#ifdef ENABLE_DECODING
36159b3361Sopenharmony_ci
37159b3361Sopenharmony_ci#include "adebug.h"
38159b3361Sopenharmony_ci
39159b3361Sopenharmony_ci#include "DecodeStream.h"
40159b3361Sopenharmony_ci
41159b3361Sopenharmony_ci// static methods
42159b3361Sopenharmony_ci
43159b3361Sopenharmony_ciDecodeStream * DecodeStream::Create()
44159b3361Sopenharmony_ci{
45159b3361Sopenharmony_ci	DecodeStream * Result;
46159b3361Sopenharmony_ci
47159b3361Sopenharmony_ci	Result = new DecodeStream;
48159b3361Sopenharmony_ci
49159b3361Sopenharmony_ci	return Result;
50159b3361Sopenharmony_ci}
51159b3361Sopenharmony_ci
52159b3361Sopenharmony_ciconst bool DecodeStream::Erase(const DecodeStream * a_ACMStream)
53159b3361Sopenharmony_ci{
54159b3361Sopenharmony_ci	delete a_ACMStream;
55159b3361Sopenharmony_ci	return true;
56159b3361Sopenharmony_ci}
57159b3361Sopenharmony_ci
58159b3361Sopenharmony_ci// class methods
59159b3361Sopenharmony_ci
60159b3361Sopenharmony_ciDecodeStream::DecodeStream() :
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("MPG123stream"); /// \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, "DecodeStream Creation (0X%08X)",this);
88159b3361Sopenharmony_ci	}
89159b3361Sopenharmony_ci	else {
90159b3361Sopenharmony_ci		ADbg debug;
91159b3361Sopenharmony_ci		debug.OutPut("DecodeStream::ACMACMStream : Impossible to create my_debug");
92159b3361Sopenharmony_ci	}
93159b3361Sopenharmony_ci
94159b3361Sopenharmony_ci}
95159b3361Sopenharmony_ci
96159b3361Sopenharmony_ciDecodeStream::~DecodeStream()
97159b3361Sopenharmony_ci{
98159b3361Sopenharmony_ci//	lame_close( gfp );
99159b3361Sopenharmony_ci
100159b3361Sopenharmony_ci	if (my_debug != NULL)
101159b3361Sopenharmony_ci	{
102159b3361Sopenharmony_ci		my_debug->OutPut(DEBUG_LEVEL_FUNC_START, "DecodeStream Deletion (0X%08X)",this);
103159b3361Sopenharmony_ci		delete my_debug;
104159b3361Sopenharmony_ci	}
105159b3361Sopenharmony_ci}
106159b3361Sopenharmony_ci
107159b3361Sopenharmony_cibool DecodeStream::init(const int nSamplesPerSec, const int nChannels, const int nAvgBytesPerSec, const int nSourceBitrate)
108159b3361Sopenharmony_ci{
109159b3361Sopenharmony_ci	bool bResult = false;
110159b3361Sopenharmony_ci
111159b3361Sopenharmony_ci	my_SamplesPerSec  = nSamplesPerSec;
112159b3361Sopenharmony_ci	my_Channels       = nChannels;
113159b3361Sopenharmony_ci	my_AvgBytesPerSec = nAvgBytesPerSec;
114159b3361Sopenharmony_ci	my_SourceBitrate  = nSourceBitrate;
115159b3361Sopenharmony_ci
116159b3361Sopenharmony_ci	bResult = true;
117159b3361Sopenharmony_ci
118159b3361Sopenharmony_ci	return bResult;
119159b3361Sopenharmony_ci}
120159b3361Sopenharmony_ci
121159b3361Sopenharmony_cibool DecodeStream::open()
122159b3361Sopenharmony_ci{
123159b3361Sopenharmony_ci	bool bResult = false;
124159b3361Sopenharmony_ci
125159b3361Sopenharmony_ci	bResult = bool(InitMP3(&my_DecodeData) != 0);
126159b3361Sopenharmony_ci
127159b3361Sopenharmony_ci	return bResult;
128159b3361Sopenharmony_ci}
129159b3361Sopenharmony_ci
130159b3361Sopenharmony_cibool DecodeStream::close(LPBYTE pOutputBuffer, DWORD *pOutputSize)
131159b3361Sopenharmony_ci{
132159b3361Sopenharmony_ci
133159b3361Sopenharmony_ci	bool bResult = false;
134159b3361Sopenharmony_ci/*
135159b3361Sopenharmony_ci	int nOutputSamples = 0;
136159b3361Sopenharmony_ci
137159b3361Sopenharmony_ci    nOutputSamples = lame_encode_flush( gfp, pOutputBuffer, 0 );
138159b3361Sopenharmony_ci
139159b3361Sopenharmony_ci	if ( nOutputSamples < 0 )
140159b3361Sopenharmony_ci	{
141159b3361Sopenharmony_ci		// BUFFER_TOO_SMALL
142159b3361Sopenharmony_ci		*pOutputSize = 0;
143159b3361Sopenharmony_ci	}
144159b3361Sopenharmony_ci	else
145159b3361Sopenharmony_ci	{
146159b3361Sopenharmony_ci		*pOutputSize = nOutputSamples;
147159b3361Sopenharmony_ci
148159b3361Sopenharmony_ci		bResult = true;
149159b3361Sopenharmony_ci	}
150159b3361Sopenharmony_ci/*
151159b3361Sopenharmony_ci	// lame will be close in VbrWriteTag function
152159b3361Sopenharmony_ci	if ( !lame_get_bWriteVbrTag( gfp ) )
153159b3361Sopenharmony_ci	{
154159b3361Sopenharmony_ci		// clean up of allocated memory
155159b3361Sopenharmony_ci		lame_close( gfp );
156159b3361Sopenharmony_ci	}
157159b3361Sopenharmony_ci*/
158159b3361Sopenharmony_ci
159159b3361Sopenharmony_ci	ExitMP3(&my_DecodeData);
160159b3361Sopenharmony_ci
161159b3361Sopenharmony_ci	bResult = true;
162159b3361Sopenharmony_ci
163159b3361Sopenharmony_ci	return bResult;
164159b3361Sopenharmony_ci}
165159b3361Sopenharmony_ci
166159b3361Sopenharmony_ciDWORD DecodeStream::GetOutputSizeForInput(const DWORD the_SrcLength) const
167159b3361Sopenharmony_ci{
168159b3361Sopenharmony_ci	DWORD Result;
169159b3361Sopenharmony_ci
170159b3361Sopenharmony_ci	double OutputInputRatio = double(my_SamplesPerSec * 2 * my_Channels) / double(my_SourceBitrate);
171159b3361Sopenharmony_ci
172159b3361Sopenharmony_ci	OutputInputRatio *= 1.15; // allow 15% more
173159b3361Sopenharmony_ci
174159b3361Sopenharmony_ci	Result = DWORD(double(the_SrcLength) * OutputInputRatio);
175159b3361Sopenharmony_ci
176159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_CODE, "Result = %d (OutputInputRatio = %f)",Result,OutputInputRatio);
177159b3361Sopenharmony_ci
178159b3361Sopenharmony_ci	return Result;
179159b3361Sopenharmony_ci}
180159b3361Sopenharmony_ci
181159b3361Sopenharmony_cibool DecodeStream::ConvertBuffer(LPACMDRVSTREAMHEADER a_StreamHeader)
182159b3361Sopenharmony_ci{
183159b3361Sopenharmony_ci	bool result = false;
184159b3361Sopenharmony_ci
185159b3361Sopenharmony_ciif (my_debug != NULL)
186159b3361Sopenharmony_ci{
187159b3361Sopenharmony_cimy_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "enter DecodeStream::ConvertBuffer");
188159b3361Sopenharmony_ci}
189159b3361Sopenharmony_ci
190159b3361Sopenharmony_ci	int ProcessedBytes;
191159b3361Sopenharmony_ci
192159b3361Sopenharmony_ci	int ret = decodeMP3(&my_DecodeData, a_StreamHeader->pbSrc, a_StreamHeader->cbSrcLength, (char *)a_StreamHeader->pbDst, a_StreamHeader->cbDstLength, &ProcessedBytes);
193159b3361Sopenharmony_ci
194159b3361Sopenharmony_ci	switch (ret)
195159b3361Sopenharmony_ci	{
196159b3361Sopenharmony_ci	    case MP3_OK:
197159b3361Sopenharmony_ci			a_StreamHeader->cbSrcLengthUsed = a_StreamHeader->cbSrcLength;
198159b3361Sopenharmony_ci			a_StreamHeader->cbDstLengthUsed = ProcessedBytes;
199159b3361Sopenharmony_ci			result = true;
200159b3361Sopenharmony_ci			break;
201159b3361Sopenharmony_ci	    case MP3_NEED_MORE:
202159b3361Sopenharmony_ci			a_StreamHeader->cbSrcLengthUsed = 0;
203159b3361Sopenharmony_ci	a_StreamHeader->cbDstLengthUsed = 0;
204159b3361Sopenharmony_ci			break;
205159b3361Sopenharmony_ci	    case MP3_ERR:
206159b3361Sopenharmony_ci			break;
207159b3361Sopenharmony_ci	}
208159b3361Sopenharmony_ci
209159b3361Sopenharmony_ci/*
210159b3361Sopenharmony_ci	DWORD InSize = a_StreamHeader->cbSrcLength / 2, OutSize = a_StreamHeader->cbDstLength; // 2 for 8<->16 bits
211159b3361Sopenharmony_ci
212159b3361Sopenharmony_ci// Encode it
213159b3361Sopenharmony_ciint dwSamples;
214159b3361Sopenharmony_ci	int nOutputSamples = 0;
215159b3361Sopenharmony_ci
216159b3361Sopenharmony_ci	dwSamples = InSize / lame_get_num_channels( gfp );
217159b3361Sopenharmony_ci
218159b3361Sopenharmony_ci	if ( 1 == lame_get_num_channels( gfp ) )
219159b3361Sopenharmony_ci	{
220159b3361Sopenharmony_ci		nOutputSamples = lame_encode_buffer(gfp,(PSHORT)a_StreamHeader->pbSrc,(PSHORT)a_StreamHeader->pbSrc,dwSamples,a_StreamHeader->pbDst,a_StreamHeader->cbDstLength);
221159b3361Sopenharmony_ci	}
222159b3361Sopenharmony_ci	else
223159b3361Sopenharmony_ci	{
224159b3361Sopenharmony_ci		nOutputSamples = lame_encode_buffer_interleaved(gfp,(PSHORT)a_StreamHeader->pbSrc,dwSamples,a_StreamHeader->pbDst,a_StreamHeader->cbDstLength);
225159b3361Sopenharmony_ci	}
226159b3361Sopenharmony_ci
227159b3361Sopenharmony_ci	a_StreamHeader->cbSrcLengthUsed = a_StreamHeader->cbSrcLength;
228159b3361Sopenharmony_ci	a_StreamHeader->cbDstLengthUsed = nOutputSamples;
229159b3361Sopenharmony_ci
230159b3361Sopenharmony_ci	result = a_StreamHeader->cbDstLengthUsed <= a_StreamHeader->cbDstLength;
231159b3361Sopenharmony_ci*/
232159b3361Sopenharmony_ci	my_debug->OutPut(DEBUG_LEVEL_FUNC_CODE, "UsedSize = %d / EncodedSize = %d, result = %d, ret = %s", a_StreamHeader->cbSrcLengthUsed, a_StreamHeader->cbDstLengthUsed, result,
233159b3361Sopenharmony_ci		(ret == MP3_OK)?"MP3_OK":(ret == MP3_NEED_MORE)?"MP3_NEED_MORE":"error");
234159b3361Sopenharmony_ci
235159b3361Sopenharmony_ciif (my_debug != NULL)
236159b3361Sopenharmony_ci{
237159b3361Sopenharmony_cimy_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "DecodeStream::ConvertBuffer result = %d",result);
238159b3361Sopenharmony_ci}
239159b3361Sopenharmony_ci
240159b3361Sopenharmony_ci	return result;
241159b3361Sopenharmony_ci}
242159b3361Sopenharmony_ci#endif // ENABLE_DECODING
243