1 /*
2  *  ReplayGainAnalysis DLL Wrapper - DLL Wrapper for Glen Sawyer's headers
3  *  Copyright (C) 2002 John Zitterkopf (zitt@bigfoot.com)
4  *                     (http://www.zittware.com)
5  *
6  *  These comments must remain intact in all copies of the source code.
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2.1 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  *  concept and filter values by David Robinson (David@Robinson.org)
23  *    -- blame him if you think the idea is flawed
24  *  coding by Glen Sawyer (mp3gain@hotmail.com) 735 W 255 N, Orem, UT 84057-4505 USA
25  *    -- blame him if you think this runs too slowly, or the coding is otherwise flawed
26  *  DLL Wrapper code for VC++5.0 by John Zitterkopf (zitt@bigfoot.com)
27  *    -- blame him for nothing. This work evolves as needed.
28  *
29  *  For an explanation of the concepts and the basic algorithms involved, go to:
30  *    http://www.replaygain.org/
31  *
32  *  V1.0 - jzitt
33  *  * Based on V1.0 header source provided by Glen Sawyer
34  *  * Attempts to maintain some backward capability with V0.9 of the same source.
35  *
36  *  V1.2.1 - jzitt 9/4/2002
37  *  * Incorporates V1.2.1 MP3Gain sources.
38  *  * Adds MP3GAIN capabilities to DLL.
39  */
40 
41 /*define below tells sourcecode that we are compiling as a Win32 DLL*/
42 #ifndef asWIN32DLL
43  #define asWIN32DLL
44 #endif
45 
46 #include <windows.h>
47 #include "gain_analysis.h"
48 #include "mp3gain.h"
49 #include "rg_error.h" /*jzitt*/
50 
51 #define MAXSAMPLES 2400
52 
53 
DllMain(HANDLE hModule,unsigned long dwReason,LPVOID lpReserved)54 BOOL APIENTRY DllMain(HANDLE hModule,
55 					  unsigned long  dwReason,
56                       LPVOID lpReserved)
57 {
58 	switch(dwReason)	{
59 
60 		case DLL_PROCESS_ATTACH:
61             mp3gainerrstr = NULL;
62 			break;
63 
64 		case DLL_THREAD_ATTACH:
65 
66 			break;
67 
68 		case DLL_THREAD_DETACH:
69 
70 			break;
71 
72 		case DLL_PROCESS_DETACH:
73             if (mp3gainerrstr != NULL) {
74                 free(mp3gainerrstr);
75 				mp3gainerrstr = NULL;
76 			}
77 			break;
78 	}
79 
80 	return TRUE;
81 	UNREFERENCED_PARAMETER(lpReserved);
82 	UNREFERENCED_PARAMETER(hModule);
83 }
84 
85 
AnalyzeSamplesInterleaved(char * samples,long num_samples,int num_channels)86 int AnalyzeSamplesInterleaved(char *samples, long num_samples, int
87 num_channels)
88 {
89 
90  double leftbuf[MAXSAMPLES], rightbuf[MAXSAMPLES];
91  long i;
92  long totSamples = num_samples;
93  long nSamples   = num_samples;
94  signed short int *samp = (signed short int *)samples;
95  int  result = GAIN_ANALYSIS_ERROR;
96 
97 /* NOTES:
98  * leftbuf and rightbuf are arrays of doubles
99  * samp is a short (16-bit) integer
100  * inf is the input file
101  * totSamples is the total number of samples remaining in the input file
102  * MAXSAMPLES is the maximum number of samples to send to AnalyzeSamples at
103 once
104  */
105 
106 while (totSamples > 0)
107 {
108 
109  if (totSamples > MAXSAMPLES)
110   nSamples = MAXSAMPLES;
111  else
112   nSamples = totSamples;
113 
114  if (num_channels == 2)
115  {
116   for (i = 0; i < nSamples; i++)
117   {
118    leftbuf[i] = *samp++; /* default conversion from short to double */
119    rightbuf[i] = *samp++;
120   }
121   result = AnalyzeSamples(leftbuf,rightbuf,nSamples,2);
122   if (result != GAIN_ANALYSIS_OK) return result;
123  } //end stereo
124  else
125  { /* Just one channel (mono) */
126   for (i = 0; i < nSamples; i++)
127   {
128    leftbuf[i] = *samp++;
129   }
130   result = AnalyzeSamples(leftbuf,NULL,nSamples,1);
131   if (result != GAIN_ANALYSIS_OK) return result;
132  } //end just mono
133 
134  totSamples -= nSamples;
135 } //end while
136 
137 return result;
138 
139 }
140 
141 
GetRadioGain()142 double GetRadioGain()
143 {
144     return GetTitleGain();
145 }
146 
147 
GetAudiophileGain()148 double GetAudiophileGain()
149 {
150 	return GetAlbumGain();
151 }
152 
InitGainAnalysisAsInt(int samplingFreq)153 int InitGainAnalysisAsInt( int samplingFreq )
154 {
155 	return InitGainAnalysis( samplingFreq );
156 }
157 
158 char *thFilename;
159 int thGainchange;
160 
changeGainThread(LPVOID lpParam)161 DWORD WINAPI changeGainThread( LPVOID lpParam )
162 {
163 	changeGain(thFilename, thGainchange, thGainchange);
164 	return 0;
165 	UNREFERENCED_PARAMETER(lpParam);
166 }
167 
ChangeGainOfMP3File(char * filename,int gainchange)168 unsigned int __stdcall ChangeGainOfMP3File(char *filename, int gainchange)
169 {
170 	DWORD dwThreadID;
171 	HANDLE hThread;
172 	MSG msg;
173 
174     mp3gainerr = MP3GAIN_NOERROR;
175 	blnCancel = 0;
176     if (mp3gainerrstr != NULL) {
177         free(mp3gainerrstr);
178 		mp3gainerrstr = NULL;
179 	}
180 	thFilename = filename;
181 	thGainchange = gainchange;
182 
183 	hThread = CreateThread(NULL,0,changeGainThread,NULL,0,&dwThreadID);
184 
185 	if (hThread == NULL)
186 		return MP3GAIN_UNSPECIFED_ERROR;
187 
188     while ((MsgWaitForMultipleObjects(1, &hThread,
189 			FALSE, INFINITE, QS_ALLINPUT)) == (WAIT_OBJECT_0 + 1))
190 	{
191 		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
192 			DispatchMessage(&msg);
193 	}
194 
195     CloseHandle(hThread);
196 	return mp3gainerr;
197 }
198 
GetMP3GainError()199 unsigned int __stdcall GetMP3GainError()
200 {
201 	return mp3gainerr;
202 }
203 
GetMP3GainErrorStrLen()204 long __stdcall GetMP3GainErrorStrLen()
205 {
206 	if ((mp3gainerr == MP3GAIN_NOERROR) || (mp3gainerrstr == NULL))
207 		return 0;
208 
209 	return strlen(mp3gainerrstr);
210 }
211 
GetMP3GainErrorStr(char * buffer,int buflen)212 char * __stdcall GetMP3GainErrorStr( char * buffer, int buflen )
213 {
214 	if (buflen < 1)
215 	{
216 		//strcpy(buffer,'\0');
217 		return NULL;//buffer;
218 	}
219 
220     if ((mp3gainerr == MP3GAIN_NOERROR) || (mp3gainerrstr == NULL)) {
221         buffer[0] = '\0';
222         return buffer;
223     }
224 
225 	buffer[buflen-1] = '\0'; //don't assume buffer has extra byte at the end
226                             //for null terminator
227 
228 	return strncpy( buffer, mp3gainerrstr, buflen-1 );
229 }
230 
StopMP3GainProcessing()231 void __stdcall StopMP3GainProcessing()
232 {
233 	blnCancel = !0;
234 }
235 
attachmsgpump(HANDLE ahwnd,UINT percentdonemsg,UINT errmsg)236 int __stdcall attachmsgpump(HANDLE ahwnd, UINT percentdonemsg, UINT errmsg)
237 {
238 	apphandle = 0;
239 	apppercentdonemsg = 0;
240 	apperrmsg = 0;
241 	if (ahwnd != 0)
242 	{
243 		apphandle = ahwnd;
244 		apppercentdonemsg = percentdonemsg;
245 		apperrmsg = errmsg;
246 	}
247 
248 	/*printf("Hi, John!\n");
249 	MessageBox( 0, "Hi, John!\n", "ReplayGainDLL\n", MB_OK ); */
250 
251 	return(MP3GAIN_NOERROR); //return success
252 }
253 
GetDLLVersion(char * buffer,int buflen)254 char * GetDLLVersion( char * buffer, int buflen )
255 {
256 	if (buflen < 1)
257 	{
258 		//strcpy(buffer,'\0');
259 		return NULL;//buffer;
260 	}
261 	buffer[buflen] = '\0';
262 
263 	return strncpy( buffer, MP3GAIN_VERSION, buflen-1 );
264 }