1159b3361Sopenharmony_ci/*
2159b3361Sopenharmony_ci*	Blade DLL Interface for LAME.
3159b3361Sopenharmony_ci*
4159b3361Sopenharmony_ci*	Copyright (c) 1999 - 2002 A.L. Faber
5159b3361Sopenharmony_ci*
6159b3361Sopenharmony_ci* This library is free software; you can redistribute it and/or
7159b3361Sopenharmony_ci* modify it under the terms of the GNU Library General Public
8159b3361Sopenharmony_ci* License as published by the Free Software Foundation; either
9159b3361Sopenharmony_ci* version 2 of the License, or (at your option) any later version.
10159b3361Sopenharmony_ci*
11159b3361Sopenharmony_ci* This library is distributed in the hope that it will be useful,
12159b3361Sopenharmony_ci* but WITHOUT ANY WARRANTY; without even the implied warranty of
13159b3361Sopenharmony_ci* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14159b3361Sopenharmony_ci* Library General Public License for more details.
15159b3361Sopenharmony_ci*
16159b3361Sopenharmony_ci* You should have received a copy of the GNU Library General Public
17159b3361Sopenharmony_ci* License along with this library; if not, write to the
18159b3361Sopenharmony_ci* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19159b3361Sopenharmony_ci* Boston, MA  02111-1307, USA.
20159b3361Sopenharmony_ci*/
21159b3361Sopenharmony_ci
22159b3361Sopenharmony_ci#include <windows.h>
23159b3361Sopenharmony_ci#include <Windef.h>
24159b3361Sopenharmony_ci#include "BladeMP3EncDLL.h"
25159b3361Sopenharmony_ci#include <assert.h>
26159b3361Sopenharmony_ci#include <stdio.h>
27159b3361Sopenharmony_ci
28159b3361Sopenharmony_ci#include <lame.h>
29159b3361Sopenharmony_ci
30159b3361Sopenharmony_ci#ifdef	__cplusplus
31159b3361Sopenharmony_ciextern "C" {
32159b3361Sopenharmony_ci#endif
33159b3361Sopenharmony_ci
34159b3361Sopenharmony_ci#define         Min(A, B)       ((A) < (B) ? (A) : (B))
35159b3361Sopenharmony_ci#define         Max(A, B)       ((A) > (B) ? (A) : (B))
36159b3361Sopenharmony_ci
37159b3361Sopenharmony_ci#define _RELEASEDEBUG 0
38159b3361Sopenharmony_ci
39159b3361Sopenharmony_ci// lame_enc DLL version number
40159b3361Sopenharmony_ciconst BYTE MAJORVERSION = 1;
41159b3361Sopenharmony_ciconst BYTE MINORVERSION = 32;
42159b3361Sopenharmony_ci
43159b3361Sopenharmony_ci
44159b3361Sopenharmony_ci// Local variables
45159b3361Sopenharmony_cistatic DWORD				dwSampleBufferSize=0;
46159b3361Sopenharmony_cistatic HMODULE				gs_hModule=NULL;
47159b3361Sopenharmony_cistatic BOOL					gs_bLogFile=FALSE;
48159b3361Sopenharmony_cistatic lame_global_flags*	gfp_save = NULL;
49159b3361Sopenharmony_ci
50159b3361Sopenharmony_ci// Local function prototypes
51159b3361Sopenharmony_cistatic void dump_config( 	lame_global_flags*	gfp );
52159b3361Sopenharmony_cistatic void DebugPrintf( const char* pzFormat, ... );
53159b3361Sopenharmony_cistatic void DispErr( char const* strErr );
54159b3361Sopenharmony_cistatic void PresetOptions( lame_global_flags *gfp, LONG myPreset );
55159b3361Sopenharmony_ci
56159b3361Sopenharmony_ci
57159b3361Sopenharmony_cistatic void DebugPrintf(const char* pzFormat, ...)
58159b3361Sopenharmony_ci{
59159b3361Sopenharmony_ci    char	szBuffer[1024]={'\0',};
60159b3361Sopenharmony_ci    char	szFileName[MAX_PATH+1]={'\0',};
61159b3361Sopenharmony_ci    va_list ap;
62159b3361Sopenharmony_ci
63159b3361Sopenharmony_ci    // Get the full module (DLL) file name
64159b3361Sopenharmony_ci    GetModuleFileNameA(	gs_hModule,
65159b3361Sopenharmony_ci        szFileName,
66159b3361Sopenharmony_ci        sizeof( szFileName ) );
67159b3361Sopenharmony_ci
68159b3361Sopenharmony_ci    // change file name extention
69159b3361Sopenharmony_ci    szFileName[ strlen(szFileName) - 3 ] = 't';
70159b3361Sopenharmony_ci    szFileName[ strlen(szFileName) - 2 ] = 'x';
71159b3361Sopenharmony_ci    szFileName[ strlen(szFileName) - 1 ] = 't';
72159b3361Sopenharmony_ci
73159b3361Sopenharmony_ci    // start at beginning of the list
74159b3361Sopenharmony_ci    va_start(ap, pzFormat);
75159b3361Sopenharmony_ci
76159b3361Sopenharmony_ci    // copy it to the string buffer
77159b3361Sopenharmony_ci    _vsnprintf(szBuffer, sizeof(szBuffer), pzFormat, ap);
78159b3361Sopenharmony_ci
79159b3361Sopenharmony_ci    // log it to the file?
80159b3361Sopenharmony_ci    if ( gs_bLogFile )
81159b3361Sopenharmony_ci    {
82159b3361Sopenharmony_ci        FILE* fp = NULL;
83159b3361Sopenharmony_ci
84159b3361Sopenharmony_ci        // try to open the log file
85159b3361Sopenharmony_ci        fp=fopen( szFileName, "a+" );
86159b3361Sopenharmony_ci
87159b3361Sopenharmony_ci        // check file open result
88159b3361Sopenharmony_ci        if (fp)
89159b3361Sopenharmony_ci        {
90159b3361Sopenharmony_ci            // write string to the file
91159b3361Sopenharmony_ci            fputs(szBuffer,fp);
92159b3361Sopenharmony_ci
93159b3361Sopenharmony_ci            // close the file
94159b3361Sopenharmony_ci            fclose(fp);
95159b3361Sopenharmony_ci        }
96159b3361Sopenharmony_ci    }
97159b3361Sopenharmony_ci
98159b3361Sopenharmony_ci#if defined _DEBUG || defined _RELEASEDEBUG
99159b3361Sopenharmony_ci    OutputDebugStringA( szBuffer );
100159b3361Sopenharmony_ci#endif
101159b3361Sopenharmony_ci
102159b3361Sopenharmony_ci    va_end(ap);
103159b3361Sopenharmony_ci}
104159b3361Sopenharmony_ci
105159b3361Sopenharmony_ci
106159b3361Sopenharmony_cistatic void PresetOptions( lame_global_flags *gfp, LONG myPreset )
107159b3361Sopenharmony_ci{
108159b3361Sopenharmony_ci    switch (myPreset)
109159b3361Sopenharmony_ci    {
110159b3361Sopenharmony_ci        /*-1*/case LQP_NOPRESET:
111159b3361Sopenharmony_ci            break;
112159b3361Sopenharmony_ci
113159b3361Sopenharmony_ci        /*0*/case LQP_NORMAL_QUALITY:
114159b3361Sopenharmony_ci            /*	lame_set_quality( gfp, 5 );*/
115159b3361Sopenharmony_ci            break;
116159b3361Sopenharmony_ci
117159b3361Sopenharmony_ci        /*1*/case LQP_LOW_QUALITY:
118159b3361Sopenharmony_ci             lame_set_quality( gfp, 9 );
119159b3361Sopenharmony_ci             break;
120159b3361Sopenharmony_ci
121159b3361Sopenharmony_ci        /*2*/case LQP_HIGH_QUALITY:
122159b3361Sopenharmony_ci             lame_set_quality( gfp, 2 );
123159b3361Sopenharmony_ci             break;
124159b3361Sopenharmony_ci
125159b3361Sopenharmony_ci        /*3*/case LQP_VOICE_QUALITY:				// --voice flag for experimental voice mode
126159b3361Sopenharmony_ci             lame_set_mode( gfp, MONO );
127159b3361Sopenharmony_ci             lame_set_preset( gfp, 56);
128159b3361Sopenharmony_ci             break;
129159b3361Sopenharmony_ci
130159b3361Sopenharmony_ci        /*4*/case LQP_R3MIX:					// --R3MIX
131159b3361Sopenharmony_ci             lame_set_preset( gfp, R3MIX);
132159b3361Sopenharmony_ci             break;
133159b3361Sopenharmony_ci
134159b3361Sopenharmony_ci        /*5*/case LQP_VERYHIGH_QUALITY:
135159b3361Sopenharmony_ci             lame_set_quality( gfp, 0 );
136159b3361Sopenharmony_ci             break;
137159b3361Sopenharmony_ci
138159b3361Sopenharmony_ci        /*6*/case LQP_STANDARD:				// --PRESET STANDARD
139159b3361Sopenharmony_ci            lame_set_preset( gfp, STANDARD);
140159b3361Sopenharmony_ci            break;
141159b3361Sopenharmony_ci
142159b3361Sopenharmony_ci        /*7*/case LQP_FAST_STANDARD:				// --PRESET FAST STANDARD
143159b3361Sopenharmony_ci            lame_set_preset( gfp, STANDARD_FAST);
144159b3361Sopenharmony_ci            break;
145159b3361Sopenharmony_ci
146159b3361Sopenharmony_ci        /*8*/case LQP_EXTREME:				// --PRESET EXTREME
147159b3361Sopenharmony_ci            lame_set_preset( gfp, EXTREME);
148159b3361Sopenharmony_ci            break;
149159b3361Sopenharmony_ci
150159b3361Sopenharmony_ci        /*9*/case LQP_FAST_EXTREME:				// --PRESET FAST EXTREME:
151159b3361Sopenharmony_ci            lame_set_preset( gfp, EXTREME_FAST);
152159b3361Sopenharmony_ci            break;
153159b3361Sopenharmony_ci
154159b3361Sopenharmony_ci        /*10*/case LQP_INSANE:				// --PRESET INSANE
155159b3361Sopenharmony_ci            lame_set_preset( gfp, INSANE);
156159b3361Sopenharmony_ci            break;
157159b3361Sopenharmony_ci
158159b3361Sopenharmony_ci        /*11*/case LQP_ABR:					// --PRESET ABR
159159b3361Sopenharmony_ci            // handled in beInitStream
160159b3361Sopenharmony_ci            break;
161159b3361Sopenharmony_ci
162159b3361Sopenharmony_ci        /*12*/case LQP_CBR:					// --PRESET CBR
163159b3361Sopenharmony_ci            // handled in beInitStream
164159b3361Sopenharmony_ci            break;
165159b3361Sopenharmony_ci
166159b3361Sopenharmony_ci        /*13*/case LQP_MEDIUM:					// --PRESET MEDIUM
167159b3361Sopenharmony_ci            lame_set_preset( gfp, MEDIUM);
168159b3361Sopenharmony_ci            break;
169159b3361Sopenharmony_ci
170159b3361Sopenharmony_ci        /*14*/case LQP_FAST_MEDIUM:					// --PRESET FAST MEDIUM
171159b3361Sopenharmony_ci            lame_set_preset( gfp, MEDIUM_FAST);
172159b3361Sopenharmony_ci            break;
173159b3361Sopenharmony_ci
174159b3361Sopenharmony_ci        /*1000*/case LQP_PHONE:
175159b3361Sopenharmony_ci            lame_set_mode( gfp, MONO );
176159b3361Sopenharmony_ci            lame_set_preset( gfp, 16);
177159b3361Sopenharmony_ci            break;
178159b3361Sopenharmony_ci
179159b3361Sopenharmony_ci        /*2000*/case LQP_SW:
180159b3361Sopenharmony_ci            lame_set_mode( gfp, MONO );
181159b3361Sopenharmony_ci            lame_set_preset( gfp, 24);
182159b3361Sopenharmony_ci            break;
183159b3361Sopenharmony_ci
184159b3361Sopenharmony_ci        /*3000*/case LQP_AM:
185159b3361Sopenharmony_ci            lame_set_mode( gfp, MONO );
186159b3361Sopenharmony_ci            lame_set_preset( gfp, 40);
187159b3361Sopenharmony_ci            break;
188159b3361Sopenharmony_ci
189159b3361Sopenharmony_ci        /*4000*/case LQP_FM:
190159b3361Sopenharmony_ci            lame_set_preset( gfp, 112);
191159b3361Sopenharmony_ci            break;
192159b3361Sopenharmony_ci
193159b3361Sopenharmony_ci        /*5000*/case LQP_VOICE:
194159b3361Sopenharmony_ci            lame_set_mode( gfp, MONO );
195159b3361Sopenharmony_ci            lame_set_preset( gfp, 56);
196159b3361Sopenharmony_ci            break;
197159b3361Sopenharmony_ci
198159b3361Sopenharmony_ci        /*6000*/case LQP_RADIO:
199159b3361Sopenharmony_ci            lame_set_preset( gfp, 112);
200159b3361Sopenharmony_ci            break;
201159b3361Sopenharmony_ci
202159b3361Sopenharmony_ci        /*7000*/case LQP_TAPE:
203159b3361Sopenharmony_ci            lame_set_preset( gfp, 112);
204159b3361Sopenharmony_ci            break;
205159b3361Sopenharmony_ci
206159b3361Sopenharmony_ci        /*8000*/case LQP_HIFI:
207159b3361Sopenharmony_ci            lame_set_preset( gfp, 160);
208159b3361Sopenharmony_ci            break;
209159b3361Sopenharmony_ci
210159b3361Sopenharmony_ci        /*9000*/case LQP_CD:
211159b3361Sopenharmony_ci            lame_set_preset( gfp, 192);
212159b3361Sopenharmony_ci            break;
213159b3361Sopenharmony_ci
214159b3361Sopenharmony_ci        /*10000*/case LQP_STUDIO:
215159b3361Sopenharmony_ci            lame_set_preset( gfp, 256);
216159b3361Sopenharmony_ci            break;
217159b3361Sopenharmony_ci
218159b3361Sopenharmony_ci    }
219159b3361Sopenharmony_ci}
220159b3361Sopenharmony_ci
221159b3361Sopenharmony_ci
222159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR	beInitStream(PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream)
223159b3361Sopenharmony_ci{
224159b3361Sopenharmony_ci    int actual_bitrate;
225159b3361Sopenharmony_ci    //2001-12-18
226159b3361Sopenharmony_ci    BE_CONFIG			lameConfig = { 0, };
227159b3361Sopenharmony_ci    int					nInitReturn = 0;
228159b3361Sopenharmony_ci    lame_global_flags*	gfp = NULL;
229159b3361Sopenharmony_ci
230159b3361Sopenharmony_ci    // Init the global flags structure
231159b3361Sopenharmony_ci    gfp = lame_init();
232159b3361Sopenharmony_ci    *phbeStream = (HBE_STREAM)gfp;
233159b3361Sopenharmony_ci
234159b3361Sopenharmony_ci    // clear out structure
235159b3361Sopenharmony_ci    memset(&lameConfig,0x00,CURRENT_STRUCT_SIZE);
236159b3361Sopenharmony_ci
237159b3361Sopenharmony_ci    // Check if this is a regular BLADE_ENCODER header
238159b3361Sopenharmony_ci    if (pbeConfig->dwConfig!=BE_CONFIG_LAME)
239159b3361Sopenharmony_ci    {
240159b3361Sopenharmony_ci        int nCRC=pbeConfig->format.mp3.bCRC;
241159b3361Sopenharmony_ci        int nVBR=(nCRC>>12)&0x0F;
242159b3361Sopenharmony_ci
243159b3361Sopenharmony_ci        // Copy parameter from old Blade structure
244159b3361Sopenharmony_ci        lameConfig.format.LHV1.dwSampleRate	=pbeConfig->format.mp3.dwSampleRate;
245159b3361Sopenharmony_ci        //for low bitrates, LAME will automatically downsample for better
246159b3361Sopenharmony_ci        //sound quality.  Forcing output samplerate = input samplerate is not a good idea
247159b3361Sopenharmony_ci        //unless the user specifically requests it:
248159b3361Sopenharmony_ci        //lameConfig.format.LHV1.dwReSampleRate=pbeConfig->format.mp3.dwSampleRate;
249159b3361Sopenharmony_ci        lameConfig.format.LHV1.nMode		=(pbeConfig->format.mp3.byMode&0x0F);
250159b3361Sopenharmony_ci        lameConfig.format.LHV1.dwBitrate	=pbeConfig->format.mp3.wBitrate;
251159b3361Sopenharmony_ci        lameConfig.format.LHV1.bPrivate		=pbeConfig->format.mp3.bPrivate;
252159b3361Sopenharmony_ci        lameConfig.format.LHV1.bOriginal	=pbeConfig->format.mp3.bOriginal;
253159b3361Sopenharmony_ci        lameConfig.format.LHV1.bCRC		=nCRC&0x01;
254159b3361Sopenharmony_ci        lameConfig.format.LHV1.bCopyright	=pbeConfig->format.mp3.bCopyright;
255159b3361Sopenharmony_ci
256159b3361Sopenharmony_ci        // Fill out the unknowns
257159b3361Sopenharmony_ci        lameConfig.format.LHV1.dwStructSize=CURRENT_STRUCT_SIZE;
258159b3361Sopenharmony_ci        lameConfig.format.LHV1.dwStructVersion=CURRENT_STRUCT_VERSION;
259159b3361Sopenharmony_ci
260159b3361Sopenharmony_ci        // Get VBR setting from fourth nibble
261159b3361Sopenharmony_ci        if ( nVBR>0 )
262159b3361Sopenharmony_ci        {
263159b3361Sopenharmony_ci            lameConfig.format.LHV1.bWriteVBRHeader = TRUE;
264159b3361Sopenharmony_ci            lameConfig.format.LHV1.bEnableVBR = TRUE;
265159b3361Sopenharmony_ci            lameConfig.format.LHV1.nVBRQuality = nVBR-1;
266159b3361Sopenharmony_ci        }
267159b3361Sopenharmony_ci
268159b3361Sopenharmony_ci        // Get Quality from third nibble
269159b3361Sopenharmony_ci        lameConfig.format.LHV1.nPreset=((nCRC>>8)&0x0F);
270159b3361Sopenharmony_ci
271159b3361Sopenharmony_ci    }
272159b3361Sopenharmony_ci    else
273159b3361Sopenharmony_ci    {
274159b3361Sopenharmony_ci        // Copy the parameters
275159b3361Sopenharmony_ci        memcpy(&lameConfig,pbeConfig,pbeConfig->format.LHV1.dwStructSize);
276159b3361Sopenharmony_ci    }
277159b3361Sopenharmony_ci
278159b3361Sopenharmony_ci    // --------------- Set arguments to LAME encoder -------------------------
279159b3361Sopenharmony_ci
280159b3361Sopenharmony_ci    // Set input sample frequency
281159b3361Sopenharmony_ci    lame_set_in_samplerate( gfp, lameConfig.format.LHV1.dwSampleRate );
282159b3361Sopenharmony_ci
283159b3361Sopenharmony_ci    // disable INFO/VBR tag by default.
284159b3361Sopenharmony_ci    // if this tag is used, the calling program must call beWriteVBRTag()
285159b3361Sopenharmony_ci    // after encoding.  But the original DLL documentation does not
286159b3361Sopenharmony_ci    // require the
287159b3361Sopenharmony_ci    // app to call beWriteVBRTag() unless they have specifically
288159b3361Sopenharmony_ci    // set LHV1.bWriteVBRHeader=TRUE.  Thus the default setting should
289159b3361Sopenharmony_ci    // be disabled.
290159b3361Sopenharmony_ci    lame_set_bWriteVbrTag( gfp, 0 );
291159b3361Sopenharmony_ci
292159b3361Sopenharmony_ci    //2001-12-18 Dibrom's ABR preset stuff
293159b3361Sopenharmony_ci
294159b3361Sopenharmony_ci    if(lameConfig.format.LHV1.nPreset == LQP_ABR)		// --ALT-PRESET ABR
295159b3361Sopenharmony_ci    {
296159b3361Sopenharmony_ci        actual_bitrate = lameConfig.format.LHV1.dwVbrAbr_bps / 1000;
297159b3361Sopenharmony_ci
298159b3361Sopenharmony_ci        // limit range
299159b3361Sopenharmony_ci        if( actual_bitrate > 320)
300159b3361Sopenharmony_ci        {
301159b3361Sopenharmony_ci            actual_bitrate = 320;
302159b3361Sopenharmony_ci        }
303159b3361Sopenharmony_ci
304159b3361Sopenharmony_ci        if( actual_bitrate < 8 )
305159b3361Sopenharmony_ci        {
306159b3361Sopenharmony_ci            actual_bitrate = 8;
307159b3361Sopenharmony_ci        }
308159b3361Sopenharmony_ci
309159b3361Sopenharmony_ci        lame_set_preset( gfp, actual_bitrate );
310159b3361Sopenharmony_ci    }
311159b3361Sopenharmony_ci
312159b3361Sopenharmony_ci    // end Dibrom's ABR preset 2001-12-18 ****** START OF CBR
313159b3361Sopenharmony_ci
314159b3361Sopenharmony_ci    if(lameConfig.format.LHV1.nPreset == LQP_CBR)		// --ALT-PRESET CBR
315159b3361Sopenharmony_ci    {
316159b3361Sopenharmony_ci        actual_bitrate = lameConfig.format.LHV1.dwBitrate;
317159b3361Sopenharmony_ci        lame_set_preset(gfp, actual_bitrate);
318159b3361Sopenharmony_ci        lame_set_VBR(gfp, vbr_off);
319159b3361Sopenharmony_ci    }
320159b3361Sopenharmony_ci
321159b3361Sopenharmony_ci    // end Dibrom's CBR preset 2001-12-18
322159b3361Sopenharmony_ci
323159b3361Sopenharmony_ci    // The following settings only used when preset is not one of the LAME QUALITY Presets
324159b3361Sopenharmony_ci    if ( (int)lameConfig.format.LHV1.nPreset < (int) LQP_STANDARD )
325159b3361Sopenharmony_ci    {
326159b3361Sopenharmony_ci        switch ( lameConfig.format.LHV1.nMode )
327159b3361Sopenharmony_ci        {
328159b3361Sopenharmony_ci        case BE_MP3_MODE_STEREO:
329159b3361Sopenharmony_ci            lame_set_mode( gfp, STEREO );
330159b3361Sopenharmony_ci            lame_set_num_channels( gfp, 2 );
331159b3361Sopenharmony_ci            break;
332159b3361Sopenharmony_ci        case BE_MP3_MODE_JSTEREO:
333159b3361Sopenharmony_ci            lame_set_mode( gfp, JOINT_STEREO );
334159b3361Sopenharmony_ci            //lame_set_force_ms( gfp, bForceMS ); // no check box to force this?
335159b3361Sopenharmony_ci            lame_set_num_channels( gfp, 2 );
336159b3361Sopenharmony_ci            break;
337159b3361Sopenharmony_ci        case BE_MP3_MODE_MONO:
338159b3361Sopenharmony_ci            lame_set_mode( gfp, MONO );
339159b3361Sopenharmony_ci            lame_set_num_channels( gfp, 1 );
340159b3361Sopenharmony_ci            break;
341159b3361Sopenharmony_ci        case BE_MP3_MODE_DUALCHANNEL:
342159b3361Sopenharmony_ci            lame_set_mode( gfp, DUAL_CHANNEL );
343159b3361Sopenharmony_ci            lame_set_num_channels( gfp, 2 );
344159b3361Sopenharmony_ci            break;
345159b3361Sopenharmony_ci        default:
346159b3361Sopenharmony_ci            {
347159b3361Sopenharmony_ci                DebugPrintf("Invalid lameConfig.format.LHV1.nMode, value is %d\n",lameConfig.format.LHV1.nMode);
348159b3361Sopenharmony_ci                return BE_ERR_INVALID_FORMAT_PARAMETERS;
349159b3361Sopenharmony_ci            }
350159b3361Sopenharmony_ci        }
351159b3361Sopenharmony_ci
352159b3361Sopenharmony_ci        if ( lameConfig.format.LHV1.bEnableVBR )
353159b3361Sopenharmony_ci        {
354159b3361Sopenharmony_ci            /* set VBR quality */
355159b3361Sopenharmony_ci            lame_set_VBR_q( gfp, lameConfig.format.LHV1.nVBRQuality );
356159b3361Sopenharmony_ci
357159b3361Sopenharmony_ci            /* select proper VBR method */
358159b3361Sopenharmony_ci            switch ( lameConfig.format.LHV1.nVbrMethod)
359159b3361Sopenharmony_ci            {
360159b3361Sopenharmony_ci            case VBR_METHOD_NONE:
361159b3361Sopenharmony_ci                lame_set_VBR( gfp, vbr_off );
362159b3361Sopenharmony_ci                break;
363159b3361Sopenharmony_ci
364159b3361Sopenharmony_ci            case VBR_METHOD_DEFAULT:
365159b3361Sopenharmony_ci                lame_set_VBR( gfp, vbr_default );
366159b3361Sopenharmony_ci                break;
367159b3361Sopenharmony_ci
368159b3361Sopenharmony_ci            case VBR_METHOD_OLD:
369159b3361Sopenharmony_ci                lame_set_VBR( gfp, vbr_rh );
370159b3361Sopenharmony_ci                break;
371159b3361Sopenharmony_ci
372159b3361Sopenharmony_ci            case VBR_METHOD_MTRH:
373159b3361Sopenharmony_ci            case VBR_METHOD_NEW:
374159b3361Sopenharmony_ci                /*
375159b3361Sopenharmony_ci                * the --vbr-mtrh commandline switch is obsolete.
376159b3361Sopenharmony_ci                * now --vbr-mtrh is known as --vbr-new
377159b3361Sopenharmony_ci                */
378159b3361Sopenharmony_ci                lame_set_VBR( gfp, vbr_mtrh );
379159b3361Sopenharmony_ci                break;
380159b3361Sopenharmony_ci
381159b3361Sopenharmony_ci            case VBR_METHOD_ABR:
382159b3361Sopenharmony_ci                lame_set_VBR( gfp, vbr_abr );
383159b3361Sopenharmony_ci                break;
384159b3361Sopenharmony_ci
385159b3361Sopenharmony_ci            default:
386159b3361Sopenharmony_ci                /* unsupported VBR method */
387159b3361Sopenharmony_ci                assert( FALSE );
388159b3361Sopenharmony_ci            }
389159b3361Sopenharmony_ci        }
390159b3361Sopenharmony_ci        else
391159b3361Sopenharmony_ci        {
392159b3361Sopenharmony_ci            /* use CBR encoding method, so turn off VBR */
393159b3361Sopenharmony_ci            lame_set_VBR( gfp, vbr_off );
394159b3361Sopenharmony_ci        }
395159b3361Sopenharmony_ci
396159b3361Sopenharmony_ci        /* Set bitrate.  (CDex users always specify bitrate=Min bitrate when using VBR) */
397159b3361Sopenharmony_ci        lame_set_brate( gfp, lameConfig.format.LHV1.dwBitrate );
398159b3361Sopenharmony_ci
399159b3361Sopenharmony_ci        /* check if we have to use ABR, in order to backwards compatible, this
400159b3361Sopenharmony_ci        * condition should still be checked indepedent of the nVbrMethod method
401159b3361Sopenharmony_ci        */
402159b3361Sopenharmony_ci        if (lameConfig.format.LHV1.dwVbrAbr_bps > 0 )
403159b3361Sopenharmony_ci        {
404159b3361Sopenharmony_ci            /* set VBR method to ABR */
405159b3361Sopenharmony_ci            lame_set_VBR( gfp, vbr_abr );
406159b3361Sopenharmony_ci
407159b3361Sopenharmony_ci            /* calculate to kbps, round to nearest kbps */
408159b3361Sopenharmony_ci            lame_set_VBR_mean_bitrate_kbps( gfp, ( lameConfig.format.LHV1.dwVbrAbr_bps + 500 ) / 1000 );
409159b3361Sopenharmony_ci
410159b3361Sopenharmony_ci            /* limit range */
411159b3361Sopenharmony_ci            if( lame_get_VBR_mean_bitrate_kbps( gfp ) > 320)
412159b3361Sopenharmony_ci            {
413159b3361Sopenharmony_ci                lame_set_VBR_mean_bitrate_kbps( gfp, 320 );
414159b3361Sopenharmony_ci            }
415159b3361Sopenharmony_ci
416159b3361Sopenharmony_ci            if( lame_get_VBR_mean_bitrate_kbps( gfp ) < 8 )
417159b3361Sopenharmony_ci            {
418159b3361Sopenharmony_ci                lame_set_VBR_mean_bitrate_kbps( gfp, 8 );
419159b3361Sopenharmony_ci            }
420159b3361Sopenharmony_ci        }
421159b3361Sopenharmony_ci
422159b3361Sopenharmony_ci    }
423159b3361Sopenharmony_ci
424159b3361Sopenharmony_ci    // First set all the preset options
425159b3361Sopenharmony_ci    if ( LQP_NOPRESET !=  lameConfig.format.LHV1.nPreset )
426159b3361Sopenharmony_ci    {
427159b3361Sopenharmony_ci        PresetOptions( gfp, lameConfig.format.LHV1.nPreset );
428159b3361Sopenharmony_ci    }
429159b3361Sopenharmony_ci
430159b3361Sopenharmony_ci
431159b3361Sopenharmony_ci    // Set frequency resampling rate, if specified
432159b3361Sopenharmony_ci    if ( lameConfig.format.LHV1.dwReSampleRate > 0 )
433159b3361Sopenharmony_ci    {
434159b3361Sopenharmony_ci        lame_set_out_samplerate( gfp, lameConfig.format.LHV1.dwReSampleRate );
435159b3361Sopenharmony_ci    }
436159b3361Sopenharmony_ci
437159b3361Sopenharmony_ci
438159b3361Sopenharmony_ci    switch ( lameConfig.format.LHV1.nMode )
439159b3361Sopenharmony_ci    {
440159b3361Sopenharmony_ci    case BE_MP3_MODE_MONO:
441159b3361Sopenharmony_ci        lame_set_mode( gfp, MONO );
442159b3361Sopenharmony_ci        lame_set_num_channels( gfp, 1 );
443159b3361Sopenharmony_ci        break;
444159b3361Sopenharmony_ci
445159b3361Sopenharmony_ci    default:
446159b3361Sopenharmony_ci        break;
447159b3361Sopenharmony_ci    }
448159b3361Sopenharmony_ci
449159b3361Sopenharmony_ci
450159b3361Sopenharmony_ci    // Use strict ISO encoding?
451159b3361Sopenharmony_ci    lame_set_strict_ISO( gfp, ( lameConfig.format.LHV1.bStrictIso ) ? 1 : 0 );
452159b3361Sopenharmony_ci
453159b3361Sopenharmony_ci    // Set copyright flag?
454159b3361Sopenharmony_ci    if ( lameConfig.format.LHV1.bCopyright )
455159b3361Sopenharmony_ci    {
456159b3361Sopenharmony_ci        lame_set_copyright( gfp, 1 );
457159b3361Sopenharmony_ci    }
458159b3361Sopenharmony_ci
459159b3361Sopenharmony_ci    // Do we have to tag  it as non original
460159b3361Sopenharmony_ci    if ( !lameConfig.format.LHV1.bOriginal )
461159b3361Sopenharmony_ci    {
462159b3361Sopenharmony_ci        lame_set_original( gfp, 0 );
463159b3361Sopenharmony_ci    }
464159b3361Sopenharmony_ci    else
465159b3361Sopenharmony_ci    {
466159b3361Sopenharmony_ci        lame_set_original( gfp, 1 );
467159b3361Sopenharmony_ci    }
468159b3361Sopenharmony_ci
469159b3361Sopenharmony_ci    // Add CRC?
470159b3361Sopenharmony_ci    if ( lameConfig.format.LHV1.bCRC )
471159b3361Sopenharmony_ci    {
472159b3361Sopenharmony_ci        lame_set_error_protection( gfp, 1 );
473159b3361Sopenharmony_ci    }
474159b3361Sopenharmony_ci    else
475159b3361Sopenharmony_ci    {
476159b3361Sopenharmony_ci        lame_set_error_protection( gfp, 0 );
477159b3361Sopenharmony_ci    }
478159b3361Sopenharmony_ci
479159b3361Sopenharmony_ci    // Set private bit?
480159b3361Sopenharmony_ci    if ( lameConfig.format.LHV1.bPrivate )
481159b3361Sopenharmony_ci    {
482159b3361Sopenharmony_ci        lame_set_extension( gfp, 1 );
483159b3361Sopenharmony_ci    }
484159b3361Sopenharmony_ci    else
485159b3361Sopenharmony_ci    {
486159b3361Sopenharmony_ci        lame_set_extension( gfp, 0 );
487159b3361Sopenharmony_ci    }
488159b3361Sopenharmony_ci
489159b3361Sopenharmony_ci
490159b3361Sopenharmony_ci    // Set VBR min bitrate, if specified
491159b3361Sopenharmony_ci    if ( lameConfig.format.LHV1.dwBitrate > 0 )
492159b3361Sopenharmony_ci    {
493159b3361Sopenharmony_ci        lame_set_VBR_min_bitrate_kbps( gfp, lameConfig.format.LHV1.dwBitrate );
494159b3361Sopenharmony_ci    }
495159b3361Sopenharmony_ci
496159b3361Sopenharmony_ci    // Set Maxbitrate, if specified
497159b3361Sopenharmony_ci    if ( lameConfig.format.LHV1.dwMaxBitrate > 0 )
498159b3361Sopenharmony_ci    {
499159b3361Sopenharmony_ci        lame_set_VBR_max_bitrate_kbps( gfp, lameConfig.format.LHV1.dwMaxBitrate );
500159b3361Sopenharmony_ci    }
501159b3361Sopenharmony_ci    // Set bit resovoir option
502159b3361Sopenharmony_ci    if ( lameConfig.format.LHV1.bNoRes )
503159b3361Sopenharmony_ci    {
504159b3361Sopenharmony_ci        lame_set_disable_reservoir( gfp,1 );
505159b3361Sopenharmony_ci    }
506159b3361Sopenharmony_ci
507159b3361Sopenharmony_ci    // check if the VBR tag is required
508159b3361Sopenharmony_ci    if ( lameConfig.format.LHV1.bWriteVBRHeader )
509159b3361Sopenharmony_ci    {
510159b3361Sopenharmony_ci        lame_set_bWriteVbrTag( gfp, 1 );
511159b3361Sopenharmony_ci    }
512159b3361Sopenharmony_ci    else
513159b3361Sopenharmony_ci    {
514159b3361Sopenharmony_ci        lame_set_bWriteVbrTag( gfp, 0 );
515159b3361Sopenharmony_ci    }
516159b3361Sopenharmony_ci
517159b3361Sopenharmony_ci    // Override Quality setting, use HIGHBYTE = NOT LOWBYTE to be backwards compatible
518159b3361Sopenharmony_ci    if (	( lameConfig.format.LHV1.nQuality & 0xFF ) ==
519159b3361Sopenharmony_ci        ((~( lameConfig.format.LHV1.nQuality >> 8 )) & 0xFF) )
520159b3361Sopenharmony_ci    {
521159b3361Sopenharmony_ci        lame_set_quality( gfp, lameConfig.format.LHV1.nQuality & 0xFF );
522159b3361Sopenharmony_ci    }
523159b3361Sopenharmony_ci
524159b3361Sopenharmony_ci    if ( 0 != ( nInitReturn = lame_init_params( gfp ) ) )
525159b3361Sopenharmony_ci    {
526159b3361Sopenharmony_ci        return nInitReturn;
527159b3361Sopenharmony_ci    }
528159b3361Sopenharmony_ci
529159b3361Sopenharmony_ci    //LAME encoding call will accept any number of samples.
530159b3361Sopenharmony_ci    if ( 0 == lame_get_version( gfp ) )
531159b3361Sopenharmony_ci    {
532159b3361Sopenharmony_ci        // For MPEG-II, only 576 samples per frame per channel
533159b3361Sopenharmony_ci        *dwSamples= 576 * lame_get_num_channels( gfp );
534159b3361Sopenharmony_ci    }
535159b3361Sopenharmony_ci    else
536159b3361Sopenharmony_ci    {
537159b3361Sopenharmony_ci        // For MPEG-I, 1152 samples per frame per channel
538159b3361Sopenharmony_ci        *dwSamples= 1152 * lame_get_num_channels( gfp );
539159b3361Sopenharmony_ci    }
540159b3361Sopenharmony_ci
541159b3361Sopenharmony_ci    // Set the input sample buffer size, so we know what we can expect
542159b3361Sopenharmony_ci    dwSampleBufferSize = *dwSamples;
543159b3361Sopenharmony_ci
544159b3361Sopenharmony_ci    // Set MP3 buffer size, conservative estimate
545159b3361Sopenharmony_ci    *dwBufferSize=(DWORD)( 1.25 * ( *dwSamples / lame_get_num_channels( gfp ) ) + 7200 );
546159b3361Sopenharmony_ci
547159b3361Sopenharmony_ci    // For debugging purposes
548159b3361Sopenharmony_ci    dump_config( gfp );
549159b3361Sopenharmony_ci
550159b3361Sopenharmony_ci    // Everything went OK, thus return SUCCESSFUL
551159b3361Sopenharmony_ci    return BE_ERR_SUCCESSFUL;
552159b3361Sopenharmony_ci}
553159b3361Sopenharmony_ci
554159b3361Sopenharmony_ci
555159b3361Sopenharmony_ci
556159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR	beFlushNoGap(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput)
557159b3361Sopenharmony_ci{
558159b3361Sopenharmony_ci    int nOutputSamples = 0;
559159b3361Sopenharmony_ci
560159b3361Sopenharmony_ci    lame_global_flags*	gfp = (lame_global_flags*)hbeStream;
561159b3361Sopenharmony_ci
562159b3361Sopenharmony_ci    // Init the global flags structure
563159b3361Sopenharmony_ci    nOutputSamples = lame_encode_flush_nogap( gfp, pOutput, LAME_MAXMP3BUFFER );
564159b3361Sopenharmony_ci
565159b3361Sopenharmony_ci    if ( nOutputSamples < 0 )
566159b3361Sopenharmony_ci    {
567159b3361Sopenharmony_ci        *pdwOutput = 0;
568159b3361Sopenharmony_ci        return BE_ERR_BUFFER_TOO_SMALL;
569159b3361Sopenharmony_ci    }
570159b3361Sopenharmony_ci    else
571159b3361Sopenharmony_ci    {
572159b3361Sopenharmony_ci        *pdwOutput = nOutputSamples;
573159b3361Sopenharmony_ci    }
574159b3361Sopenharmony_ci
575159b3361Sopenharmony_ci    return BE_ERR_SUCCESSFUL;
576159b3361Sopenharmony_ci}
577159b3361Sopenharmony_ci
578159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR	beDeinitStream(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput)
579159b3361Sopenharmony_ci{
580159b3361Sopenharmony_ci    int nOutputSamples = 0;
581159b3361Sopenharmony_ci
582159b3361Sopenharmony_ci    lame_global_flags*	gfp = (lame_global_flags*)hbeStream;
583159b3361Sopenharmony_ci
584159b3361Sopenharmony_ci    nOutputSamples = lame_encode_flush( gfp, pOutput, 0 );
585159b3361Sopenharmony_ci
586159b3361Sopenharmony_ci    if ( nOutputSamples < 0 )
587159b3361Sopenharmony_ci    {
588159b3361Sopenharmony_ci        *pdwOutput = 0;
589159b3361Sopenharmony_ci        return BE_ERR_BUFFER_TOO_SMALL;
590159b3361Sopenharmony_ci    }
591159b3361Sopenharmony_ci    else
592159b3361Sopenharmony_ci    {
593159b3361Sopenharmony_ci        *pdwOutput = nOutputSamples;
594159b3361Sopenharmony_ci    }
595159b3361Sopenharmony_ci
596159b3361Sopenharmony_ci    return BE_ERR_SUCCESSFUL;
597159b3361Sopenharmony_ci}
598159b3361Sopenharmony_ci
599159b3361Sopenharmony_ci
600159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR	beCloseStream(HBE_STREAM hbeStream)
601159b3361Sopenharmony_ci{
602159b3361Sopenharmony_ci    lame_global_flags*	gfp = (lame_global_flags*)hbeStream;
603159b3361Sopenharmony_ci
604159b3361Sopenharmony_ci    // lame will be close in VbrWriteTag function
605159b3361Sopenharmony_ci    if ( !lame_get_bWriteVbrTag( gfp ) )
606159b3361Sopenharmony_ci    {
607159b3361Sopenharmony_ci        // clean up of allocated memory
608159b3361Sopenharmony_ci        lame_close( gfp );
609159b3361Sopenharmony_ci
610159b3361Sopenharmony_ci        gfp_save = NULL;
611159b3361Sopenharmony_ci    }
612159b3361Sopenharmony_ci    else
613159b3361Sopenharmony_ci    {
614159b3361Sopenharmony_ci        gfp_save = (lame_global_flags*)hbeStream;
615159b3361Sopenharmony_ci    }
616159b3361Sopenharmony_ci
617159b3361Sopenharmony_ci    // DeInit encoder
618159b3361Sopenharmony_ci    return BE_ERR_SUCCESSFUL;
619159b3361Sopenharmony_ci}
620159b3361Sopenharmony_ci
621159b3361Sopenharmony_ci
622159b3361Sopenharmony_ci
623159b3361Sopenharmony_ci__declspec(dllexport) VOID		beVersion(PBE_VERSION pbeVersion)
624159b3361Sopenharmony_ci{
625159b3361Sopenharmony_ci    // DLL Release date
626159b3361Sopenharmony_ci    char lpszDate[20]	= { '\0', };
627159b3361Sopenharmony_ci    char lpszTemp[5]	= { '\0', };
628159b3361Sopenharmony_ci    lame_version_t lv   = { 0, };
629159b3361Sopenharmony_ci
630159b3361Sopenharmony_ci
631159b3361Sopenharmony_ci    // Set DLL interface version
632159b3361Sopenharmony_ci    pbeVersion->byDLLMajorVersion=MAJORVERSION;
633159b3361Sopenharmony_ci    pbeVersion->byDLLMinorVersion=MINORVERSION;
634159b3361Sopenharmony_ci
635159b3361Sopenharmony_ci    get_lame_version_numerical ( &lv );
636159b3361Sopenharmony_ci
637159b3361Sopenharmony_ci    // Set Engine version number (Same as Lame version)
638159b3361Sopenharmony_ci    pbeVersion->byMajorVersion = (BYTE)lv.major;
639159b3361Sopenharmony_ci    pbeVersion->byMinorVersion = (BYTE)lv.minor;
640159b3361Sopenharmony_ci    pbeVersion->byAlphaLevel   = (BYTE)lv.alpha;
641159b3361Sopenharmony_ci    pbeVersion->byBetaLevel    = (BYTE)lv.beta;
642159b3361Sopenharmony_ci
643159b3361Sopenharmony_ci#ifdef MMX_choose_table
644159b3361Sopenharmony_ci    pbeVersion->byMMXEnabled=1;
645159b3361Sopenharmony_ci#else
646159b3361Sopenharmony_ci    pbeVersion->byMMXEnabled=0;
647159b3361Sopenharmony_ci#endif
648159b3361Sopenharmony_ci
649159b3361Sopenharmony_ci    memset( pbeVersion->btReserved, 0, sizeof( pbeVersion->btReserved ) );
650159b3361Sopenharmony_ci
651159b3361Sopenharmony_ci    // Get compilation date
652159b3361Sopenharmony_ci    strcpy(lpszDate,__DATE__);
653159b3361Sopenharmony_ci
654159b3361Sopenharmony_ci    // Get the first three character, which is the month
655159b3361Sopenharmony_ci    strncpy(lpszTemp,lpszDate,3);
656159b3361Sopenharmony_ci    lpszTemp[3] = '\0';
657159b3361Sopenharmony_ci    pbeVersion->byMonth=1;
658159b3361Sopenharmony_ci
659159b3361Sopenharmony_ci    // Set month
660159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Jan")==0)	pbeVersion->byMonth = 1;
661159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Feb")==0)	pbeVersion->byMonth = 2;
662159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Mar")==0)	pbeVersion->byMonth = 3;
663159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Apr")==0)	pbeVersion->byMonth = 4;
664159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"May")==0)	pbeVersion->byMonth = 5;
665159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Jun")==0)	pbeVersion->byMonth = 6;
666159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Jul")==0)	pbeVersion->byMonth = 7;
667159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Aug")==0)	pbeVersion->byMonth = 8;
668159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Sep")==0)	pbeVersion->byMonth = 9;
669159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Oct")==0)	pbeVersion->byMonth = 10;
670159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Nov")==0)	pbeVersion->byMonth = 11;
671159b3361Sopenharmony_ci    if (strcmp(lpszTemp,"Dec")==0)	pbeVersion->byMonth = 12;
672159b3361Sopenharmony_ci
673159b3361Sopenharmony_ci    // Get day of month string (char [4..5])
674159b3361Sopenharmony_ci    pbeVersion->byDay = (BYTE) atoi( lpszDate + 4 );
675159b3361Sopenharmony_ci
676159b3361Sopenharmony_ci    // Get year of compilation date (char [7..10])
677159b3361Sopenharmony_ci    pbeVersion->wYear = (WORD) atoi( lpszDate + 7 );
678159b3361Sopenharmony_ci
679159b3361Sopenharmony_ci    memset( pbeVersion->zHomepage, 0x00, BE_MAX_HOMEPAGE );
680159b3361Sopenharmony_ci
681159b3361Sopenharmony_ci    strcpy( pbeVersion->zHomepage, "https://lame.sourceforge.io/" );
682159b3361Sopenharmony_ci}
683159b3361Sopenharmony_ci
684159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR	beEncodeChunk(HBE_STREAM hbeStream, DWORD nSamples,
685159b3361Sopenharmony_ci                                              PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput)
686159b3361Sopenharmony_ci{
687159b3361Sopenharmony_ci    // Encode it
688159b3361Sopenharmony_ci    int dwSamples;
689159b3361Sopenharmony_ci    int	nOutputSamples = 0;
690159b3361Sopenharmony_ci    lame_global_flags*	gfp = (lame_global_flags*)hbeStream;
691159b3361Sopenharmony_ci
692159b3361Sopenharmony_ci    dwSamples = nSamples / lame_get_num_channels( gfp );
693159b3361Sopenharmony_ci
694159b3361Sopenharmony_ci    // old versions of lame_enc.dll required exactly 1152 samples
695159b3361Sopenharmony_ci    // and worked even if nSamples accidently set to 2304
696159b3361Sopenharmony_ci    // simulate this behavoir:
697159b3361Sopenharmony_ci    if ( 1 == lame_get_num_channels( gfp ) && nSamples == 2304)
698159b3361Sopenharmony_ci    {
699159b3361Sopenharmony_ci        dwSamples/= 2;
700159b3361Sopenharmony_ci    }
701159b3361Sopenharmony_ci
702159b3361Sopenharmony_ci
703159b3361Sopenharmony_ci    if ( 1 == lame_get_num_channels( gfp ) )
704159b3361Sopenharmony_ci    {
705159b3361Sopenharmony_ci        nOutputSamples = lame_encode_buffer(gfp,pSamples,pSamples,dwSamples,pOutput,0);
706159b3361Sopenharmony_ci    }
707159b3361Sopenharmony_ci    else
708159b3361Sopenharmony_ci    {
709159b3361Sopenharmony_ci        nOutputSamples = lame_encode_buffer_interleaved(gfp,pSamples,dwSamples,pOutput,0);
710159b3361Sopenharmony_ci    }
711159b3361Sopenharmony_ci
712159b3361Sopenharmony_ci
713159b3361Sopenharmony_ci    if ( nOutputSamples < 0 )
714159b3361Sopenharmony_ci    {
715159b3361Sopenharmony_ci        *pdwOutput=0;
716159b3361Sopenharmony_ci        return BE_ERR_BUFFER_TOO_SMALL;
717159b3361Sopenharmony_ci    }
718159b3361Sopenharmony_ci    else
719159b3361Sopenharmony_ci    {
720159b3361Sopenharmony_ci        *pdwOutput = (DWORD)nOutputSamples;
721159b3361Sopenharmony_ci    }
722159b3361Sopenharmony_ci
723159b3361Sopenharmony_ci    return BE_ERR_SUCCESSFUL;
724159b3361Sopenharmony_ci}
725159b3361Sopenharmony_ci
726159b3361Sopenharmony_ci
727159b3361Sopenharmony_ci// accept floating point audio samples, scaled to the range of a signed 16-bit
728159b3361Sopenharmony_ci//  integer (within +/- 32768), in non-interleaved channels  -- DSPguru, jd
729159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR	beEncodeChunkFloatS16NI(HBE_STREAM hbeStream, DWORD nSamples,
730159b3361Sopenharmony_ci                                                        PFLOAT buffer_l, PFLOAT buffer_r, PBYTE pOutput, PDWORD pdwOutput)
731159b3361Sopenharmony_ci{
732159b3361Sopenharmony_ci    int nOutputSamples;
733159b3361Sopenharmony_ci    lame_global_flags*	gfp = (lame_global_flags*)hbeStream;
734159b3361Sopenharmony_ci
735159b3361Sopenharmony_ci    nOutputSamples = lame_encode_buffer_float(gfp,buffer_l,buffer_r,nSamples,pOutput,0);
736159b3361Sopenharmony_ci
737159b3361Sopenharmony_ci    if ( nOutputSamples >= 0 )
738159b3361Sopenharmony_ci    {
739159b3361Sopenharmony_ci        *pdwOutput = (DWORD) nOutputSamples;
740159b3361Sopenharmony_ci    }
741159b3361Sopenharmony_ci    else
742159b3361Sopenharmony_ci    {
743159b3361Sopenharmony_ci        *pdwOutput=0;
744159b3361Sopenharmony_ci        return BE_ERR_BUFFER_TOO_SMALL;
745159b3361Sopenharmony_ci    }
746159b3361Sopenharmony_ci
747159b3361Sopenharmony_ci    return BE_ERR_SUCCESSFUL;
748159b3361Sopenharmony_ci}
749159b3361Sopenharmony_ci
750159b3361Sopenharmony_cistatic int
751159b3361Sopenharmony_cimaybeSyncWord(FILE* fpStream)
752159b3361Sopenharmony_ci{
753159b3361Sopenharmony_ci    unsigned char mp3_frame_header[4];
754159b3361Sopenharmony_ci    size_t nbytes = fread(mp3_frame_header, 1, sizeof(mp3_frame_header), fpStream);
755159b3361Sopenharmony_ci    if ( nbytes != sizeof(mp3_frame_header) ) {
756159b3361Sopenharmony_ci        return -1;
757159b3361Sopenharmony_ci    }
758159b3361Sopenharmony_ci    if ( mp3_frame_header[0] != 0xffu ) {
759159b3361Sopenharmony_ci        return -1; /* doesn't look like a sync word */
760159b3361Sopenharmony_ci    }
761159b3361Sopenharmony_ci    if ( (mp3_frame_header[1] & 0xE0u) != 0xE0u ) {
762159b3361Sopenharmony_ci        return -1; /* doesn't look like a sync word */
763159b3361Sopenharmony_ci    }
764159b3361Sopenharmony_ci    return 0;
765159b3361Sopenharmony_ci}
766159b3361Sopenharmony_ci
767159b3361Sopenharmony_cistatic int
768159b3361Sopenharmony_ciskipId3v2(FILE * fpStream, size_t lametag_frame_size)
769159b3361Sopenharmony_ci{
770159b3361Sopenharmony_ci    size_t  nbytes;
771159b3361Sopenharmony_ci    size_t  id3v2TagSize = 0;
772159b3361Sopenharmony_ci    unsigned char id3v2Header[10];
773159b3361Sopenharmony_ci
774159b3361Sopenharmony_ci    /* seek to the beginning of the stream */
775159b3361Sopenharmony_ci    if (fseek(fpStream, 0, SEEK_SET) != 0) {
776159b3361Sopenharmony_ci        return -2;  /* not seekable, abort */
777159b3361Sopenharmony_ci    }
778159b3361Sopenharmony_ci    /* read 10 bytes in case there's an ID3 version 2 header here */
779159b3361Sopenharmony_ci    nbytes = fread(id3v2Header, 1, sizeof(id3v2Header), fpStream);
780159b3361Sopenharmony_ci    if (nbytes != sizeof(id3v2Header)) {
781159b3361Sopenharmony_ci        return -3;  /* not readable, maybe opened Write-Only */
782159b3361Sopenharmony_ci    }
783159b3361Sopenharmony_ci    /* does the stream begin with the ID3 version 2 file identifier? */
784159b3361Sopenharmony_ci    if (!strncmp((char *) id3v2Header, "ID3", 3)) {
785159b3361Sopenharmony_ci        /* the tag size (minus the 10-byte header) is encoded into four
786159b3361Sopenharmony_ci        * bytes where the most significant bit is clear in each byte
787159b3361Sopenharmony_ci        */
788159b3361Sopenharmony_ci        id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21)
789159b3361Sopenharmony_ci            | ((id3v2Header[7] & 0x7f) << 14)
790159b3361Sopenharmony_ci            | ((id3v2Header[8] & 0x7f) << 7)
791159b3361Sopenharmony_ci            | (id3v2Header[9] & 0x7f))
792159b3361Sopenharmony_ci            + sizeof id3v2Header;
793159b3361Sopenharmony_ci    }
794159b3361Sopenharmony_ci    /* Seek to the beginning of the audio stream */
795159b3361Sopenharmony_ci    if ( fseek(fpStream, id3v2TagSize, SEEK_SET) != 0 ) {
796159b3361Sopenharmony_ci        return -2;
797159b3361Sopenharmony_ci    }
798159b3361Sopenharmony_ci    if ( maybeSyncWord(fpStream) != 0) {
799159b3361Sopenharmony_ci        return -1;
800159b3361Sopenharmony_ci    }
801159b3361Sopenharmony_ci    if ( fseek(fpStream, id3v2TagSize+lametag_frame_size, SEEK_SET) != 0 ) {
802159b3361Sopenharmony_ci        return -2;
803159b3361Sopenharmony_ci    }
804159b3361Sopenharmony_ci    if ( maybeSyncWord(fpStream) != 0) {
805159b3361Sopenharmony_ci        return -1;
806159b3361Sopenharmony_ci    }
807159b3361Sopenharmony_ci    /* OK, it seems we found our LAME-Tag/Xing frame again */
808159b3361Sopenharmony_ci    /* Seek to the beginning of the audio stream */
809159b3361Sopenharmony_ci    if ( fseek(fpStream, id3v2TagSize, SEEK_SET) != 0 ) {
810159b3361Sopenharmony_ci        return -2;
811159b3361Sopenharmony_ci    }
812159b3361Sopenharmony_ci    return 0;
813159b3361Sopenharmony_ci}
814159b3361Sopenharmony_ci
815159b3361Sopenharmony_cistatic BE_ERR
816159b3361Sopenharmony_ciupdateLameTagFrame(lame_global_flags* gfp, FILE* fpStream)
817159b3361Sopenharmony_ci{
818159b3361Sopenharmony_ci    size_t n = lame_get_lametag_frame( gfp, 0, 0 ); /* ask for bufer size */
819159b3361Sopenharmony_ci
820159b3361Sopenharmony_ci    if ( n > 0 )
821159b3361Sopenharmony_ci    {
822159b3361Sopenharmony_ci        unsigned char* buffer = 0;
823159b3361Sopenharmony_ci        size_t m = 1;
824159b3361Sopenharmony_ci
825159b3361Sopenharmony_ci        if ( 0 != skipId3v2(fpStream, n) )
826159b3361Sopenharmony_ci        {
827159b3361Sopenharmony_ci            DispErr( "Error updating LAME-tag frame:\n\n"
828159b3361Sopenharmony_ci                     "can't locate old frame\n" );
829159b3361Sopenharmony_ci            return BE_ERR_INVALID_FORMAT_PARAMETERS;
830159b3361Sopenharmony_ci        }
831159b3361Sopenharmony_ci
832159b3361Sopenharmony_ci        buffer = (unsigned char*)malloc( n );
833159b3361Sopenharmony_ci
834159b3361Sopenharmony_ci        if ( buffer == 0 )
835159b3361Sopenharmony_ci        {
836159b3361Sopenharmony_ci            DispErr( "Error updating LAME-tag frame:\n\n"
837159b3361Sopenharmony_ci                     "can't allocate frame buffer\n" );
838159b3361Sopenharmony_ci            return BE_ERR_INVALID_FORMAT_PARAMETERS;
839159b3361Sopenharmony_ci        }
840159b3361Sopenharmony_ci
841159b3361Sopenharmony_ci        /* Put it all to disk again */
842159b3361Sopenharmony_ci        n = lame_get_lametag_frame( gfp, buffer, n );
843159b3361Sopenharmony_ci        if ( n > 0 )
844159b3361Sopenharmony_ci        {
845159b3361Sopenharmony_ci            m = fwrite( buffer, n, 1, fpStream );
846159b3361Sopenharmony_ci        }
847159b3361Sopenharmony_ci        free( buffer );
848159b3361Sopenharmony_ci
849159b3361Sopenharmony_ci        if ( m != 1 )
850159b3361Sopenharmony_ci        {
851159b3361Sopenharmony_ci            DispErr( "Error updating LAME-tag frame:\n\n"
852159b3361Sopenharmony_ci                     "couldn't write frame into file\n" );
853159b3361Sopenharmony_ci            return BE_ERR_INVALID_FORMAT_PARAMETERS;
854159b3361Sopenharmony_ci        }
855159b3361Sopenharmony_ci    }
856159b3361Sopenharmony_ci    return BE_ERR_SUCCESSFUL;
857159b3361Sopenharmony_ci}
858159b3361Sopenharmony_ci
859159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beWriteInfoTag( HBE_STREAM hbeStream,
860159b3361Sopenharmony_ci                                            LPCSTR lpszFileName )
861159b3361Sopenharmony_ci{
862159b3361Sopenharmony_ci    FILE* fpStream	= NULL;
863159b3361Sopenharmony_ci    BE_ERR beResult	= BE_ERR_SUCCESSFUL;
864159b3361Sopenharmony_ci
865159b3361Sopenharmony_ci    lame_global_flags*	gfp = (lame_global_flags*)hbeStream;
866159b3361Sopenharmony_ci
867159b3361Sopenharmony_ci    if ( NULL != gfp )
868159b3361Sopenharmony_ci    {
869159b3361Sopenharmony_ci        // Do we have to write the VBR tag?
870159b3361Sopenharmony_ci        if ( lame_get_bWriteVbrTag( gfp ) )
871159b3361Sopenharmony_ci        {
872159b3361Sopenharmony_ci            // Try to open the file
873159b3361Sopenharmony_ci            fpStream=fopen( lpszFileName, "rb+" );
874159b3361Sopenharmony_ci
875159b3361Sopenharmony_ci            // Check file open result
876159b3361Sopenharmony_ci            if ( NULL == fpStream )
877159b3361Sopenharmony_ci            {
878159b3361Sopenharmony_ci                beResult = BE_ERR_INVALID_FORMAT_PARAMETERS;
879159b3361Sopenharmony_ci                DispErr( "Error updating LAME-tag frame:\n\n"
880159b3361Sopenharmony_ci                         "can't open file for reading and writing\n" );
881159b3361Sopenharmony_ci            }
882159b3361Sopenharmony_ci            else
883159b3361Sopenharmony_ci            {
884159b3361Sopenharmony_ci                beResult = updateLameTagFrame( gfp, fpStream );
885159b3361Sopenharmony_ci
886159b3361Sopenharmony_ci                // Close the file stream
887159b3361Sopenharmony_ci                fclose( fpStream );
888159b3361Sopenharmony_ci            }
889159b3361Sopenharmony_ci        }
890159b3361Sopenharmony_ci
891159b3361Sopenharmony_ci        // clean up of allocated memory
892159b3361Sopenharmony_ci        lame_close( gfp );
893159b3361Sopenharmony_ci    }
894159b3361Sopenharmony_ci    else
895159b3361Sopenharmony_ci    {
896159b3361Sopenharmony_ci        beResult = BE_ERR_INVALID_FORMAT_PARAMETERS;
897159b3361Sopenharmony_ci    }
898159b3361Sopenharmony_ci
899159b3361Sopenharmony_ci    // return result
900159b3361Sopenharmony_ci    return beResult;
901159b3361Sopenharmony_ci}
902159b3361Sopenharmony_ci
903159b3361Sopenharmony_ci// for backwards compatiblity
904159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beWriteVBRHeader(LPCSTR lpszFileName)
905159b3361Sopenharmony_ci{
906159b3361Sopenharmony_ci    return beWriteInfoTag( (HBE_STREAM)gfp_save, lpszFileName );
907159b3361Sopenharmony_ci}
908159b3361Sopenharmony_ci
909159b3361Sopenharmony_ci
910159b3361Sopenharmony_ciBOOL APIENTRY DllMain(HANDLE hModule,
911159b3361Sopenharmony_ci                      DWORD  ul_reason_for_call,
912159b3361Sopenharmony_ci                      LPVOID lpReserved)
913159b3361Sopenharmony_ci{
914159b3361Sopenharmony_ci    (void) lpReserved;
915159b3361Sopenharmony_ci    gs_hModule = (HMODULE) hModule;
916159b3361Sopenharmony_ci
917159b3361Sopenharmony_ci    switch( ul_reason_for_call )
918159b3361Sopenharmony_ci    {
919159b3361Sopenharmony_ci    case DLL_PROCESS_ATTACH:
920159b3361Sopenharmony_ci        // Enable debug/logging?
921159b3361Sopenharmony_ci        gs_bLogFile = GetPrivateProfileIntA("Debug","WriteLogFile",gs_bLogFile,"lame_enc.ini");
922159b3361Sopenharmony_ci        break;
923159b3361Sopenharmony_ci    case DLL_THREAD_ATTACH:
924159b3361Sopenharmony_ci        break;
925159b3361Sopenharmony_ci    case DLL_THREAD_DETACH:
926159b3361Sopenharmony_ci        break;
927159b3361Sopenharmony_ci    case DLL_PROCESS_DETACH:
928159b3361Sopenharmony_ci        break;
929159b3361Sopenharmony_ci    }
930159b3361Sopenharmony_ci    return TRUE;
931159b3361Sopenharmony_ci}
932159b3361Sopenharmony_ci
933159b3361Sopenharmony_ci
934159b3361Sopenharmony_cistatic void dump_config( lame_global_flags* gfp )
935159b3361Sopenharmony_ci{
936159b3361Sopenharmony_ci    DebugPrintf("\n\nLame_enc configuration options:\n");
937159b3361Sopenharmony_ci    DebugPrintf("==========================================================\n");
938159b3361Sopenharmony_ci
939159b3361Sopenharmony_ci    DebugPrintf("version                =%d\n",lame_get_version( gfp ) );
940159b3361Sopenharmony_ci    DebugPrintf("Layer                  =3\n");
941159b3361Sopenharmony_ci    DebugPrintf("mode                   =");
942159b3361Sopenharmony_ci    switch ( lame_get_mode( gfp ) )
943159b3361Sopenharmony_ci    {
944159b3361Sopenharmony_ci    case STEREO:       DebugPrintf( "Stereo\n" ); break;
945159b3361Sopenharmony_ci    case JOINT_STEREO: DebugPrintf( "Joint-Stereo\n" ); break;
946159b3361Sopenharmony_ci    case DUAL_CHANNEL: DebugPrintf( "Forced Stereo\n" ); break;
947159b3361Sopenharmony_ci    case MONO:         DebugPrintf( "Mono\n" ); break;
948159b3361Sopenharmony_ci    case NOT_SET:      /* FALLTROUGH */
949159b3361Sopenharmony_ci    default:           DebugPrintf( "Error (unknown)\n" ); break;
950159b3361Sopenharmony_ci    }
951159b3361Sopenharmony_ci
952159b3361Sopenharmony_ci    DebugPrintf("Input sample rate      =%.1f kHz\n", lame_get_in_samplerate( gfp ) /1000.0 );
953159b3361Sopenharmony_ci    DebugPrintf("Output sample rate     =%.1f kHz\n", lame_get_out_samplerate( gfp ) /1000.0 );
954159b3361Sopenharmony_ci
955159b3361Sopenharmony_ci    DebugPrintf("bitrate                =%d kbps\n", lame_get_brate( gfp ) );
956159b3361Sopenharmony_ci    DebugPrintf("Quality Setting        =%d\n", lame_get_quality( gfp ) );
957159b3361Sopenharmony_ci
958159b3361Sopenharmony_ci    DebugPrintf("Low pass frequency     =%d\n", lame_get_lowpassfreq( gfp ) );
959159b3361Sopenharmony_ci    DebugPrintf("Low pass width         =%d\n", lame_get_lowpasswidth( gfp ) );
960159b3361Sopenharmony_ci
961159b3361Sopenharmony_ci    DebugPrintf("High pass frequency    =%d\n", lame_get_highpassfreq( gfp ) );
962159b3361Sopenharmony_ci    DebugPrintf("High pass width        =%d\n", lame_get_highpasswidth( gfp ) );
963159b3361Sopenharmony_ci
964159b3361Sopenharmony_ci    DebugPrintf("No short blocks        =%d\n", lame_get_no_short_blocks( gfp ) );
965159b3361Sopenharmony_ci    DebugPrintf("Force short blocks     =%d\n", lame_get_force_short_blocks( gfp ) );
966159b3361Sopenharmony_ci
967159b3361Sopenharmony_ci    DebugPrintf("de-emphasis            =%d\n", lame_get_emphasis( gfp ) );
968159b3361Sopenharmony_ci    DebugPrintf("private flag           =%d\n", lame_get_extension( gfp ) );
969159b3361Sopenharmony_ci
970159b3361Sopenharmony_ci    DebugPrintf("copyright flag         =%d\n", lame_get_copyright( gfp ) );
971159b3361Sopenharmony_ci    DebugPrintf("original flag          =%d\n",	lame_get_original( gfp ) );
972159b3361Sopenharmony_ci    DebugPrintf("CRC                    =%s\n", lame_get_error_protection( gfp ) ? "on" : "off" );
973159b3361Sopenharmony_ci    DebugPrintf("Fast mode              =%s\n", ( lame_get_quality( gfp ) )? "enabled" : "disabled" );
974159b3361Sopenharmony_ci    DebugPrintf("Force mid/side stereo  =%s\n", ( lame_get_force_ms( gfp ) )?"enabled":"disabled" );
975159b3361Sopenharmony_ci    DebugPrintf("Disable Reservoir      =%d\n", lame_get_disable_reservoir( gfp ) );
976159b3361Sopenharmony_ci    DebugPrintf("Allow diff-short       =%d\n", lame_get_allow_diff_short( gfp ) );
977159b3361Sopenharmony_ci    DebugPrintf("Interchannel masking   =%f\n", lame_get_interChRatio( gfp ) );
978159b3361Sopenharmony_ci    DebugPrintf("Strict ISO Encoding    =%s\n", ( lame_get_strict_ISO( gfp ) ) ?"Yes":"No");
979159b3361Sopenharmony_ci    DebugPrintf("Scale                  =%5.2f\n", lame_get_scale( gfp ) );
980159b3361Sopenharmony_ci
981159b3361Sopenharmony_ci    DebugPrintf("VBR                    =%s, VBR_q =%d, VBR method =",
982159b3361Sopenharmony_ci        ( lame_get_VBR( gfp ) !=vbr_off ) ? "enabled": "disabled",
983159b3361Sopenharmony_ci        lame_get_VBR_q( gfp ) );
984159b3361Sopenharmony_ci
985159b3361Sopenharmony_ci    switch ( lame_get_VBR( gfp ) )
986159b3361Sopenharmony_ci    {
987159b3361Sopenharmony_ci    case vbr_off:	DebugPrintf( "vbr_off\n" );	break;
988159b3361Sopenharmony_ci    case vbr_mt :	DebugPrintf( "vbr_mt \n" );	break;
989159b3361Sopenharmony_ci    case vbr_rh :	DebugPrintf( "vbr_rh \n" );	break;
990159b3361Sopenharmony_ci    case vbr_mtrh:	DebugPrintf( "vbr_mtrh \n" );	break;
991159b3361Sopenharmony_ci    case vbr_abr:
992159b3361Sopenharmony_ci        DebugPrintf( "vbr_abr (average bitrate %d kbps)\n", lame_get_VBR_mean_bitrate_kbps( gfp ) );
993159b3361Sopenharmony_ci        break;
994159b3361Sopenharmony_ci    default:
995159b3361Sopenharmony_ci        DebugPrintf("error, unknown VBR setting\n");
996159b3361Sopenharmony_ci        break;
997159b3361Sopenharmony_ci    }
998159b3361Sopenharmony_ci
999159b3361Sopenharmony_ci    DebugPrintf("Vbr Min bitrate        =%d kbps\n", lame_get_VBR_min_bitrate_kbps( gfp ) );
1000159b3361Sopenharmony_ci    DebugPrintf("Vbr Max bitrate        =%d kbps\n", lame_get_VBR_max_bitrate_kbps( gfp ) );
1001159b3361Sopenharmony_ci
1002159b3361Sopenharmony_ci    DebugPrintf("Write VBR Header       =%s\n", ( lame_get_bWriteVbrTag( gfp ) ) ?"Yes":"No");
1003159b3361Sopenharmony_ci    DebugPrintf("VBR Hard min           =%d\n", lame_get_VBR_hard_min( gfp ) );
1004159b3361Sopenharmony_ci
1005159b3361Sopenharmony_ci    DebugPrintf("ATH Only               =%d\n", lame_get_ATHonly( gfp ) );
1006159b3361Sopenharmony_ci    DebugPrintf("ATH short              =%d\n", lame_get_ATHshort( gfp ) );
1007159b3361Sopenharmony_ci    DebugPrintf("ATH no                 =%d\n", lame_get_noATH( gfp ) );
1008159b3361Sopenharmony_ci    DebugPrintf("ATH type               =%d\n", lame_get_ATHtype( gfp ) );
1009159b3361Sopenharmony_ci    DebugPrintf("ATH lower              =%f\n", lame_get_ATHlower( gfp ) );
1010159b3361Sopenharmony_ci    DebugPrintf("ATH aa                 =%d\n", lame_get_athaa_type( gfp ) );
1011159b3361Sopenharmony_ci    //DebugPrintf("ATH aa  loudapprox     =%d\n", lame_get_athaa_loudapprox( gfp ) );
1012159b3361Sopenharmony_ci    DebugPrintf("ATH aa  sensitivity    =%f\n", lame_get_athaa_sensitivity( gfp ) );
1013159b3361Sopenharmony_ci
1014159b3361Sopenharmony_ci    DebugPrintf("Experimental nspsytune =%d\n", lame_get_exp_nspsytune( gfp ) );
1015159b3361Sopenharmony_ci    DebugPrintf("Experimental X         =%d\n", lame_get_experimentalX( gfp ) );
1016159b3361Sopenharmony_ci    DebugPrintf("Experimental Y         =%d\n", lame_get_experimentalY( gfp ) );
1017159b3361Sopenharmony_ci    DebugPrintf("Experimental Z         =%d\n", lame_get_experimentalZ( gfp ) );
1018159b3361Sopenharmony_ci}
1019159b3361Sopenharmony_ci
1020159b3361Sopenharmony_ci
1021159b3361Sopenharmony_cistatic void DispErr(char const* strErr)
1022159b3361Sopenharmony_ci{
1023159b3361Sopenharmony_ci    MessageBoxA(NULL,strErr,"LAME_ENC.DLL",MB_OK|MB_ICONHAND);
1024159b3361Sopenharmony_ci}
1025159b3361Sopenharmony_ci
1026159b3361Sopenharmony_ci#ifdef	__cplusplus
1027159b3361Sopenharmony_ci}
1028159b3361Sopenharmony_ci#endif
1029