1
#define
MAX_LOADSTRING 100
2
#define
WM_BASSPLAY (WM_USER + 100)
3
#define
WM_BASSQUIT (WM_USER + 101)
4
5
HINSTANCE hInst;
6
HWND hMainWindow;
7
TCHAR szTitle[MAX_LOADSTRING];
8
TCHAR szWindowClass[MAX_LOADSTRING];
9
HSTREAM hStream
=
NULL;
10
HANDLE hFile
=
NULL;
11
#define
BLOCK_SIZE 17640
12
13
In_Module
*
in_module;
14
Out_Module out_module;
15
16
HMODULE hInputModule
=
NULL;
17
18
ATOM MyRegisterClass(HINSTANCE hInstance);
19
BOOL InitInstance(HINSTANCE,
int
);
20
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
21
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
22
BOOL Play();
23
BOOL LoadWinampInputPlugin();
24
BOOL UnloadWinampInputPlugin();
25
BOOL LoadWinampOutputPlugin();
26
BOOL UnloadWinampOutputPlugin();
27
28
int
APIENTRY _tWinMain(HINSTANCE hInstance,
29
HINSTANCE hPrevInstance,
30
LPTSTR lpCmdLine,
31
int
nCmdShow)
32
{
33
UNREFERENCED_PARAMETER(hPrevInstance);
34
UNREFERENCED_PARAMETER(lpCmdLine);
35
36
MSG msg;
37
HACCEL hAccelTable;
38
39
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
40
LoadString(hInstance, IDC_MINIBASSPLAYER, szWindowClass, MAX_LOADSTRING);
41
MyRegisterClass(hInstance);
42
43
if (!InitInstance (hInstance, nCmdShow))
44
{
45
return FALSE;
46
}
47
48
if(!BASS_Init(1, 44100, 0, hMainWindow, NULL))
49
{
50
MessageBox(hMainWindow, "Could not initialize Bass library.", "Error", MB_OK);
51
return 0;
52
}
53
54
BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, 10000);
55
56
if(!LoadWinampOutputPlugin())
57
{
58
BASS_Free();
59
return FALSE;
60
}
61
62
if(!LoadWinampInputPlugin())
63
{
64
UnloadWinampOutputPlugin();
65
BASS_Free();
66
return FALSE;
67
}
68
69
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MINIBASSPLAYER));
70
71
while (GetMessage(&msg, NULL, 0, 0))
72
{
73
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
74
{
75
TranslateMessage(&msg);
76
DispatchMessage(&msg);
77
}
78
}
79
80
UnloadWinampOutputPlugin();
81
UnloadWinampInputPlugin();
82
BASS_Free();
83
return (int) msg.wParam;
84
}
85
86
ATOM MyRegisterClass(HINSTANCE hInstance)
87
{
88
WNDCLASSEX wcex;
89
90
wcex.cbSize = sizeof(WNDCLASSEX);
91
92
wcex.style = CS_HREDRAW | CS_VREDRAW;
93
wcex.lpfnWndProc = WndProc;
94
wcex.cbClsExtra = 0;
95
wcex.cbWndExtra = 0;
96
wcex.hInstance = hInstance;
97
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MINIBASSPLAYER));
98
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
99
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
100
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MINIBASSPLAYER);
101
wcex.lpszClassName = szWindowClass;
102
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
103
104
return RegisterClassEx(&wcex);
105
}
106
107
BOOL InitInstance(HINSTANCE hInstance,
int
nCmdShow)
108
{
109
HWND hWnd;
110
111
hInst = hInstance;
112
113
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
114
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
115
116
if (!hWnd)
117
{
118
return FALSE;
119
}
120
121
hMainWindow = hWnd;
122
ShowWindow(hWnd, nCmdShow);
123
UpdateWindow(hWnd);
124
125
return TRUE;
126
}
127
128
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
129
{
130
int wmId, wmEvent;
131
PAINTSTRUCT ps;
132
HDC hdc;
133
134
switch (message)
135
{
136
case WM_COMMAND:
137
wmId = LOWORD(wParam);
138
wmEvent = HIWORD(wParam);
139
140
switch (wmId)
141
{
142
case IDM_ABOUT:
143
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
144
break;
145
case IDM_EXIT:
146
DestroyWindow(hWnd);
147
break;
148
case IDM_PLAY:
149
if(Play())
150
{
151
if(hStream)
152
{
153
Sleep(1000);
154
BASS_ChannelPlay(hStream, FALSE);
155
}
156
157
if(in_module)
158
in_module->SetVolume(127);
159
}
160
break;
161
default:
162
return DefWindowProc(hWnd, message, wParam, lParam);
163
}
164
break;
165
case WM_PAINT:
166
hdc = BeginPaint(hWnd, &ps);
167
EndPaint(hWnd, &ps);
168
break;
169
case WM_DESTROY:
170
if(hFile != NULL && hFile != INVALID_HANDLE_VALUE)
171
{
172
CloseHandle(hFile);
173
hFile = NULL;
174
}
175
176
PostQuitMessage(0);
177
break;
178
case WM_BASSPLAY:
179
if(hStream)
180
BASS_ChannelPlay(hStream, FALSE);
181
break;
182
case WM_BASSQUIT:
183
if(hFile != NULL && hFile != INVALID_HANDLE_VALUE)
184
{
185
CloseHandle(hFile);
186
hFile = NULL;
187
}
188
189
BASS_ChannelStop(hStream);
190
BASS_StreamFree(hStream);
191
hStream = NULL;
192
break;
193
default:
194
return DefWindowProc(hWnd, message, wParam, lParam);
195
}
196
return 0;
197
}
198
199
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
200
{
201
UNREFERENCED_PARAMETER(lParam);
202
switch (message)
203
{
204
case WM_INITDIALOG:
205
return (INT_PTR)TRUE;
206
207
case WM_COMMAND:
208
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
209
{
210
EndDialog(hDlg, LOWORD(wParam));
211
return (INT_PTR)TRUE;
212
}
213
break;
214
}
215
return (INT_PTR)FALSE;
216
}
217
218
static
DWORD readChunk(HANDLE hFile,
void
*
buf, size_t size)
219
{
220
DWORD readByes;
221
if(ReadFile(hFile, buf, size, &readByes, NULL) == FALSE)
222
return 0;
223
224
return readByes;
225
}
226
227
DWORD __stdcall StreamWriter(HSTREAM handle,
void
*
buffer, DWORD length,
void
*
user)
228
{
229
if(hFile == NULL || hFile == INVALID_HANDLE_VALUE)
230
return BASS_STREAMPROC_END;
231
232
int len = (length < BLOCK_SIZE) ? length : BLOCK_SIZE;
233
DWORD dwReadBytes = 0;
234
235
if(!ReadFile(hFile, buffer, len, &dwReadBytes, NULL))
236
{
237
SendMessage(hMainWindow, WM_BASSQUIT, 0, 0);
238
return BASS_STREAMPROC_END;
239
}
240
241
return len;
242
}
243
244
BOOL Play()
245
{
246
//WAVEFORMATEX wfx;
247
//char riff[5], wave[5], fmt[5], data[5];
248
//DWORD len, struct_len, data_len;
249
250
//if((hFile = CreateFile(
251
// "D:\\Music\\Love Story.wav", GENERIC_READ, FILE_SHARE_READ, NULL,
252
// OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) {
253
// ExitProcess(1);
254
//}
255
256
//readChunk(hFile, (void*)riff, 4);
257
//riff[4] = '\0';
258
//if(strncmp(riff, "RIFF", 4) == 0)
259
//{
260
// readChunk(hFile, (void*)&len, 4);
261
// readChunk(hFile, (void*)wave, 4);
262
// readChunk(hFile, (void*)fmt, 4);
263
// readChunk(hFile, (void*)&struct_len, 4);
264
// readChunk(hFile, (void*)&wfx, struct_len);
265
// readChunk(hFile, (void*)data, 4);
266
// readChunk(hFile, (void*)&data_len, 4);
267
//}
268
//else
269
// ExitProcess(1);
270
271
//hStream = BASS_StreamCreate(wfx.nSamplesPerSec, wfx.nChannels, 0, StreamWriter, NULL);
272
//return (hStream != NULL) ? TRUE : FALSE;
273
274
if(in_module)
275
{
276
in_module->Play("D:\\Music\\Love Story.mp3");
277
return TRUE;
278
}
279
else
280
return FALSE;
281
}
282
283
/**/
//////////////////////////////////////////////////////////////////////////
284
//
Input
285
void
SAVSAInit(
int
maxlatency_in_ms,
int
srate )
286
{
287
}
288
289
void
SAVSADeInit()
290
{
291
}
292
293
void
SAAddPCMData(
void
*
PCMData,
int
nch,
int
bps,
int
timestamp )
294
{
295
}
296
297
int
SAGetMode()
298
{
299
return 0;
300
}
301
302
void
SAAdd(
void
*
data,
int
timestamp,
int
csa )
303
{
304
}
305
306
void
VSAAddPCMData(
void
*
PCMData,
int
nch,
int
bps,
int
timestamp )
307
{
308
}
309
310
int
VSAGetMode(
int
*
specNch,
int
*
waveNch )
311
{
312
return 0;
313
}
314
315
void
VSAAdd(
void
*
data,
int
timestamp )
316
{
317
}
318
319
void
VSASetInfo(
int
nch,
int
srate )
320
{
321
}
322
323
void
SetInfo(
int
bitrate,
int
srate,
int
stereo,
int
synched )
324
{
325
}
326
327
int
dsp_isactive()
328
{
329
return 0;
330
}
331
332
int
dsp_dosamples(
short
int
*
samples,
int
numsamples,
int
bps,
int
nch,
int
srate )
333
{
334
return numsamples;
335
}
336
337
BOOL LoadWinampInputPlugin()
338
{
339
#define INPUT_PLUGIN "in_mp3.dll"
340
hInputModule = LoadLibrary(INPUT_PLUGIN);
341
if(!hInputModule)
342
return FALSE;
343
344
typedef In_Module* (__stdcall *pfn_winampGetInModule2)();
345
pfn_winampGetInModule2 winampGetInModule2 = (pfn_winampGetInModule2)GetProcAddress(hInputModule, "winampGetInModule2");
346
if(!winampGetInModule2)
347
return FALSE;
348
349
in_module = winampGetInModule2();
350
if(!in_module)
351
return FALSE;
352
353
in_module->hMainWindow = hMainWindow;
354
in_module->hDllInstance = hInputModule;
355
in_module->outMod = &out_module;
356
in_module->Init();
357
358
in_module->SetInfo = SetInfo;
359
in_module->dsp_isactive = dsp_isactive;
360
in_module->dsp_dosamples = dsp_dosamples;
361
in_module->SAVSAInit = SAVSAInit;
362
in_module->SAVSADeInit = SAVSADeInit;
363
in_module->SAAddPCMData = SAAddPCMData;
364
in_module->SAGetMode = SAGetMode;
365
in_module->SAAdd = SAAdd;
366
in_module->VSASetInfo = VSASetInfo;
367
in_module->VSAAddPCMData = VSAAddPCMData;
368
in_module->VSAGetMode = VSAGetMode;
369
in_module->VSAAdd = VSAAdd;
370
371
return TRUE;
372
}
373
374
BOOL UnloadWinampInputPlugin()
375
{
376
if(in_module)
377
in_module->Quit();
378
379
if(hInputModule)
380
FreeLibrary(hInputModule);
381
382
in_module = NULL;
383
hInputModule = NULL;
384
return TRUE;
385
}
386
387
/**/
//////////////////////////////////////////////////////////////////////////
388
//
Output
389
const
int
PacketSize
=
1152
;
390
const
int
WinampBaseSize
=
576
;
391
const
int
DefaultBufSize
=
88200
;
392
393
unsigned
char
*
pBuf
=
NULL;
394
DWORD bufSize
=
0
;
395
BOOL omodReady
=
FALSE;
396
BOOL PosChanged
=
FALSE;
397
398
DWORD rOffset
=
0
;
399
DWORD wOffset
=
0
;
400
int
SPS
=
0
;
401
int
BPS
=
0
;
402
int
Channels
=
0
;
403
DWORD BASSDataSize
=
0
;
404
BOOL isReading
=
FALSE;
405
BOOL isWriting
=
FALSE;
406
int
posDelta
=
0
;
407
__int64 totalWritten
=
0
;
408
BOOL InitialBufferFill
=
FALSE;
409
BOOL ReachedEnd
=
FALSE;
410
BOOL ResumeMode
=
0
;
411
412
BOOL Debug
=
FALSE;
413
HANDLE hRawFile
=
NULL;
414
415
static
DWORD FreeSpace(DWORD BufferSize, DWORD ReadOffset, DWORD WriteOffset)
416
{
417
if(ReadOffset > WriteOffset)
418
return ReadOffset - WriteOffset;
419
else
420
return BufferSize - WriteOffset + ReadOffset;
421
}
422
423
static
DWORD DataRemains(DWORD BufferSize, DWORD ReadOffset, DWORD WriteOffset)
424
{
425
if(ReadOffset > WriteOffset)
426
return BufferSize + WriteOffset - ReadOffset;
427
else
428
return WriteOffset - ReadOffset;
429
}
430
431
DWORD __stdcall StreamWriter2(HSTREAM handle,
void
*
buffer, DWORD length,
void
*
user)
432
{
433
unsigned char* p1 = NULL;
434
unsigned char* p2 = NULL;
435
unsigned short wCycle = 0;
436
DWORD OutputTime = 0;
437
438
if(isWriting)
439
{
440
wCycle = 0;
441
do
442
{
443
Sleep(50);
444
wCycle++;
445
} while(!isWriting || wCycle == 150);
446
}
447
448
isReading = TRUE;
449
int result = 0;
450
451
p1 = pBuf + rOffset;
452
if(rOffset > wOffset)
453
{
454
if((bufSize - rOffset) > length)
455
{
456
memcpy(buffer, p1, length);
457
rOffset += length;
458
result = length;
459
}
460
else if((bufSize - rOffset) == length)
461
{
462
memcpy(buffer, p1, length);
463
rOffset = 0;
464
result = length;
465
}
466
else
467
{
468
memcpy(buffer, p1, bufSize - rOffset);
469
unsigned char* _buffer = (unsigned char*)buffer;
470
p2 = _buffer + (bufSize - rOffset);
471
472
if((length - (bufSize - rOffset)) < wOffset)
473
{
474
memcpy(p2, pBuf, length - (bufSize - rOffset));
475
rOffset = length - (bufSize - rOffset);
476
result = length;
477
}
478
else
479
{
480
memcpy(p2, pBuf, wOffset);
481
rOffset = wOffset;
482
result = bufSize - rOffset + wOffset;
483
}
484
}
485
}
486
else if(rOffset < wOffset)
487
{
488
if((wOffset - rOffset) >= length)
489
{
490
memcpy(buffer, p1, length);
491
rOffset += length;
492
result = length;
493
}
494
else
495
{
496
memcpy(buffer, p1, wOffset - rOffset);
497
rOffset = wOffset - rOffset;
498
result = wOffset;
499
}
500
}
501
else
502
result = BASS_STREAMPROC_END;
503
504
if(ResumeMode)
505
{
506
if(DataRemains(bufSize, rOffset, wOffset) < length)
507
{
508
wCycle = 0;
509
while(!isWriting)
510
{
511
Sleep(200);
512
wCycle++;
513
if(wCycle == 50)
514
break;
515
}
516
517
ResumeMode = FALSE;
518
}
519
}
520
521
isReading = FALSE;
522
return result;
523
}
524
525
void
Config(HWND hwndParent)
526
{
527
MessageBox(hwndParent, "No configuration is needed.", "Confirm", MB_OK);
528
}
529
530
void
About(HWND hwndParent)
531
{
532
MessageBox(hwndParent, "This is a Winamp output plug-in emulator using BASS", "Confirm", MB_OK);
533
}
534
535
void
Init()
536
{
537
if(omodReady)
538
return;
539
540
omodReady = TRUE;
541
}
542
543
void
Quit()
544
{
545
if(omodReady)
546
omodReady = FALSE;
547
}
548
549
int
Open(
int
samplerate,
int
numchannels,
int
bitspersamp,
int
bufferlenms,
int
prebufferms)
550
{
551
if(!omodReady)
552
return -1;
553
554
DWORD flag = 0;
555
if(bitspersamp == 8)
556
flag = BASS_SAMPLE_8BITS;
557
558
rOffset = 0;
559
wOffset = 0;
560
totalWritten = 0;
561
isReading = FALSE;
562
isWriting = FALSE;
563
PosChanged = FALSE;
564
InitialBufferFill = TRUE;
565
ReachedEnd = FALSE;
566
567
hStream = BASS_StreamCreate(samplerate, numchannels, flag, STREAMPROC_PUSH, NULL);
568
if(!hStream)
569
return -1;
570
571
SPS = samplerate;
572
BPS = bitspersamp;
573
Channels = numchannels;
574
BASSDataSize = (SPS * (BPS >> 3) * Channels * 2) / 10;
575
576
if(((BASSDataSize * 2) > bufSize) || ((BASSDataSize * 4) < bufSize))
577
{
578
if(pBuf != NULL)
579
{
580
delete [] pBuf;
581
pBuf = NULL;
582
}
583
584
bufSize = BASSDataSize * 3;
585
pBuf = new unsigned char[bufSize];
586
if(pBuf == NULL)
587
{
588
bufSize = 0;
589
return -1;
590
}
591
}
592
593
if(Debug)
594
hRawFile = CreateFile("out.raw", GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
595
CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
596
597
posDelta = 0;
598
return 0;
599
}
600
601
void
Close()
602
{
603
if(BASS_ChannelIsActive(hStream) == BASS_ACTIVE_PLAYING)
604
BASS_ChannelStop(hStream);
605
606
BASS_StreamFree(hStream);
607
608
if(hRawFile != NULL && Debug == TRUE)
609
{
610
CloseHandle(hRawFile);
611
hRawFile = NULL;
612
}
613
614
hStream = 0;
615
}
616
617
int
Write(
char
*
buf,
int
len)
618
{
619
if(TRUE)
620
{
621
BASS_StreamPutData(hStream, buf, len);
622
return 0;
623
}
624
625
unsigned char* p1 = NULL;
626
unsigned char* p2 = NULL;
627
unsigned short wCycle = 0;
628
629
if(isReading)
630
{
631
wCycle = 0;
632
do
633
{
634
Sleep(50);
635
wCycle++;
636
} while (!isReading || wCycle == 150);
637
}
638
639
isWriting = TRUE;
640
int result = 0;
641
642
p1 = pBuf + wOffset;
643
644
if(FreeSpace(bufSize, rOffset, wOffset) > (DWORD)len)
645
{
646
if(rOffset > wOffset)
647
{
648
memcpy(p1, buf, len);
649
wOffset += len;
650
}
651
else
652
{
653
if((bufSize - wOffset) > (DWORD)len)
654
{
655
memcpy(p1, buf, len);
656
wOffset += len;
657
}
658
else
659
{
660
memcpy(p1, buf, bufSize - wOffset);
661
662
if((bufSize - wOffset) < (DWORD)len)
663
{
664
p2 = (unsigned char*)(buf + (bufSize - wOffset));
665
memcpy(pBuf, p2, len - (bufSize - wOffset));
666
}
667
668
wOffset = len - (bufSize - wOffset);
669
}
670
}
671
}
672
else
673
result = 1;
674
675
isWriting = FALSE;
676
677
if(InitialBufferFill)
678
{
679
DWORD free_space = FreeSpace(bufSize, rOffset, wOffset);
680
DWORD data_remains = DataRemains(bufSize, rOffset, wOffset);
681
DWORD xx = BASSDataSize << 1;
682
683
if(free_space <= 8192 || data_remains >= xx)
684
{
685
InitialBufferFill = FALSE;
686
if(hStream)
687
{
688
ResumeMode = FALSE;
689
BASS_ChannelPlay(hStream, TRUE);
690
}
691
}
692
}
693
694
if(hRawFile != NULL && Debug == TRUE)
695
{
696
DWORD dwWriteBytes = 0;
697
WriteFile(hRawFile, buf, len, &dwWriteBytes, NULL);
698
}
699
700
return result;
701
}
702
703
int
CanWrite()
704
{
705
if(isReading)
706
return 0;
707
708
return FreeSpace(bufSize, rOffset, wOffset) - 1;
709
}
710
711
int
IsPlaying()
712
{
713
if(BASS_ChannelIsActive(hStream) == BASS_ACTIVE_PLAYING)
714
return 1;
715
else
716
return 0;
717
}
718
719
int
Pause(
int
pause)
720
{
721
int result = 0;
722
if(BASS_ChannelIsActive(hStream) == BASS_ACTIVE_PAUSED)
723
result = 1;
724
else
725
return 0;
726
727
if((pause == 0) && (result == 1))
728
{
729
ResumeMode = TRUE;
730
BASS_ChannelPlay(hStream, FALSE);
731
}
732
else if(pause == 0)
733
{
734
ResumeMode = TRUE;
735
BASS_ChannelPlay(hStream, TRUE);
736
}
737
else if(pause != 0 && pause == 0)
738
BASS_ChannelPause(hStream);
739
740
return result;
741
}
742
743
void
SetVolume(
int
volume)
744
{
745
int SetVolume = 0;
746
if(volume < 0)
747
SetVolume = 0;
748
else if(volume > 255)
749
SetVolume = 255;
750
else
751
SetVolume = volume;
752
753
BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, SetVolume * 39);
754
}
755
756
void
SetPan(
int
pan)
757
{
758
BASS_ChannelSetAttribute(hStream, BASS_ATTRIB_PAN, (float)pan * (100 / 128));
759
}
760
761
void
Flush(
int
t)
762
{
763
DWORD chnStatus = 0;
764
BOOL wasPlaying = FALSE;
765
unsigned short wCycle = 0;
766
767
chnStatus = BASS_ChannelIsActive(hStream);
768
769
if(chnStatus != BASS_ACTIVE_PAUSED && chnStatus != BASS_ACTIVE_STOPPED)
770
if((FreeSpace(bufSize, rOffset, wOffset) > 0) || (chnStatus == BASS_ACTIVE_PLAYING))
771
wasPlaying = TRUE;
772
else
773
wasPlaying = FALSE;
774
else
775
wasPlaying = FALSE;
776
777
if(chnStatus == BASS_ACTIVE_PAUSED)
778
if(!PosChanged)
779
return;
780
781
if(isReading)
782
{
783
wCycle = 0;
784
do
785
{
786
Sleep(50);
787
wCycle++;
788
} while (!isReading || wCycle == 150);
789
}
790
791
BASS_ChannelStop(hStream);
792
793
if(wasPlaying)
794
InitialBufferFill = TRUE;
795
796
posDelta = t;
797
rOffset = 0;
798
wOffset = 0;
799
totalWritten = 0;
800
isWriting = FALSE;
801
PosChanged = FALSE;
802
}
803
804
#define
round(x) (int)((x)>0 ? (x)+0.5 : (x)-0.5)
805
806
int
GetOutputTime()
807
{
808
DWORD Devider = SPS * (BPS >> 3) * Channels;
809
if(Devider != 0)
810
return posDelta + round(1000 * BASS_ChannelGetPosition((hStream), BASS_POS_BYTE) / Devider);
811
812
return 0;
813
}
814
815
int
GetWrittenTime()
816
{
817
DWORD Devider = SPS * (BPS >> 3) * Channels;
818
if(Devider != 0)
819
return posDelta + round(1000 * totalWritten / Devider);
820
821
return 0;
822
}
823
824
BOOL LoadWinampOutputPlugin()
825
{
826
pBuf = new unsigned char[DefaultBufSize];
827
if(pBuf == NULL)
828
return FALSE;
829
830
memset(pBuf, 0, sizeof(unsigned char) * DefaultBufSize);
831
bufSize = DefaultBufSize;
832
833
out_module.version = 0x10;
834
out_module.description = "BASS Winamp output plug-in emulator";
835
out_module.id = 65536 + 1;
836
out_module.hMainWindow = hMainWindow;
837
out_module.hDllInstance = NULL;
838
out_module.Config = Config;
839
out_module.About = About;
840
out_module.Init = Init;
841
out_module.Quit = Quit;
842
out_module.Open = Open;
843
out_module.Close = Close;
844
out_module.Write = Write;
845
out_module.CanWrite = CanWrite;
846
out_module.IsPlaying = IsPlaying;
847
out_module.Pause = Pause;
848
out_module.SetVolume = SetVolume;
849
out_module.SetPan = SetPan;
850
out_module.Flush = Flush;
851
out_module.GetOutputTime = GetOutputTime;
852
out_module.GetWrittenTime = GetWrittenTime;
853
854
out_module.Init();
855
return TRUE;
856
}
857
858
BOOL UnloadWinampOutputPlugin()
859
{
860
if(pBuf != NULL)
861
{
862
delete [] pBuf;
863
pBuf = NULL;
864
}
865
866
return TRUE;
867
}
click here download source code

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32



33

34

35

36

37

38

39

40

41

42

43

44



45

46

47

48

49



50

51

52

53

54

55

56

57



58

59

60

61

62

63



64

65

66

67

68

69

70

71

72



73

74



75

76

77

78

79

80

81

82

83

84

85

86

87



88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108



109

110

111

112

113

114

115

116

117



118

119

120

121

122

123

124

125

126

127

128

129



130

131

132

133

134

135



136

137

138

139

140

141



142

143

144

145

146

147

148

149

150



151

152



153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171



172

173

174

175

176

177

178

179

180

181

182

183

184



185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200



201

202

203



204

205

206

207

208

209



210

211

212

213

214

215

216

217

218

219



220

221

222

223

224

225

226

227

228



229

230

231

232

233

234

235

236



237

238

239

240

241

242

243

244

245



246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275



276

277

278

279

280

281

282

283


284

285

286



287

288

289

290



291

292

293

294



295

296

297

298



299

300

301

302

303



304

305

306

307



308

309

310

311



312

313

314

315

316



317

318

319

320



321

322

323

324



325

326

327

328



329

330

331

332

333



334

335

336

337

338



339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375



376

377

378

379

380

381

382

383

384

385

386

387


388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416



417

418

419

420

421

422

423

424



425

426

427

428

429

430

431

432



433

434

435

436

437

438

439



440

441

442



443

444

445

446

447

448

449

450

451

452

453



454

455



456

457

458

459

460

461



462

463

464

465

466

467



468

469

470

471

472

473



474

475

476

477

478

479



480

481

482

483

484

485

486

487



488

489



490

491

492

493

494

495



496

497

498

499

500

501

502

503

504

505



506

507



508

509

510



511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526



527

528

529

530

531



532

533

534

535

536



537

538

539

540

541

542

543

544



545

546

547

548

549

550



551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577



578

579



580

581

582

583

584

585

586

587



588

589

590

591

592

593

594

595

596

597

598

599

600

601

602



603

604

605

606

607

608

609



610

611

612

613

614

615

616

617

618



619

620



621

622

623

624

625

626

627

628

629

630



631

632

633



634

635

636

637

638

639

640

641

642

643

644

645



646

647



648

649

650

651

652



653

654



655

656

657

658

659



660

661

662

663



664

665

666

667

668

669

670

671

672

673

674

675

676

677

678



679

680

681

682

683

684



685

686

687



688

689

690

691

692

693

694

695



696

697

698

699

700

701

702

703

704



705

706

707

708

709

710

711

712



713

714

715

716

717

718

719

720



721

722

723

724

725

726

727

728



729

730

731

732

733



734

735

736

737

738

739

740

741

742

743

744



745

746

747

748

749

750

751

752

753

754

755

756

757



758

759

760

761

762



763

764

765

766

767

768

769

770

771

772

773

774

775

776

777

778

779

780

781

782



783

784

785



786

787

788

789

790

791

792

793

794

795

796

797

798

799

800

801

802

803

804

805

806

807



808

809

810

811

812

813

814

815

816



817

818

819

820

821

822

823

824

825



826

827

828

829

830

831

832

833

834

835

836

837

838

839

840

841

842

843

844

845

846

847

848

849

850

851

852

853

854

855

856

857

858

859



860

861



862

863

864

865

866

867
