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 }