winamp/Src/Plugins/SDK/in_tone/MAIN.C

240 lines
4.3 KiB
C++
Raw Normal View History

2024-09-24 08:54:57 -04:00
/*
** Example Winamp input plug-in
** Copyright (c) 1998, Justin Frankel/Nullsoft Inc.
*/
#include <windows.h>
#include <mmreg.h>
#include <msacm.h>
#include <math.h>
#include <stdio.h>
#include "../Winamp/in2.h"
#define WM_WA_MPEG_EOF WM_USER+2
extern In_Module mod;
char lastfn[MAX_PATH];
short sample_buffer[576*2];
/*
// avoid CRT. Evil. Big. Bloated.
BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
*/
int paused;
DWORD WINAPI __stdcall PlayThread(void *b);
int gen_freq=2600;
int killDecodeThread=0;
HANDLE thread_handle=INVALID_HANDLE_VALUE;
void config(HWND hwndParent)
{
MessageBoxA(hwndParent,"To use, open 'tone://2600' (for 2600hz).","Configuration",MB_OK); // Must stay in ANSI
}
void about(HWND hwndParent)
{
MessageBoxA(hwndParent,"Nullsoft Tone Generator, by Justin Frankel","About Nullsoft Tone Generator",MB_OK); // Must stay in ANSI
}
int init()
{
return 0;
}
void quit() { }
int isourfile(const char *fn)
{
char buf[8];
memcpy(buf,fn,7);
buf[7]=0;
return lstrcmpA(buf,"tone://")?0:1; // Must stay in ANSI
}
int play(const char *fn) {
int maxlatency;
int tmp;
strcpy(lastfn,fn);
// simple atoi() inline so that we don't have to use libc (for a nice 4k dll)
{
const char *s=fn+7;
int n=0;
while (*s >= '0' && *s <= '9')
{
n*=10;
n += *s++ -'0';
}
gen_freq=n;
}
paused=0;
memset(sample_buffer,0,sizeof(sample_buffer));
maxlatency = mod.outMod->Open(44100,1,16, -1,-1);
if (maxlatency < 0)
{
return 1;
}
mod.SetInfo(0,44,1,1);
mod.SAVSAInit(maxlatency,44100);
mod.VSASetInfo(44100,1);
mod.outMod->SetVolume(-666);
killDecodeThread=0;
thread_handle = (HANDLE) CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) PlayThread,(void *) &killDecodeThread,0,&tmp);
return 0;
}
void pause() { paused=1; mod.outMod->Pause(1); }
void unpause() { paused=0; mod.outMod->Pause(0); }
int ispaused() { return paused; }
void stop() {
if (thread_handle != INVALID_HANDLE_VALUE)
{
killDecodeThread=1;
if (WaitForSingleObject(thread_handle,INFINITE) == WAIT_TIMEOUT)
{
MessageBoxA(mod.hMainWindow,"error asking thread to die!\n","error killing decode thread",0); // Must stay in ANSI
TerminateThread(thread_handle,0);
}
CloseHandle(thread_handle);
thread_handle = INVALID_HANDLE_VALUE;
}
mod.outMod->Close();
mod.SAVSADeInit();
}
int getlength() { return -1000; }
int getoutputtime() { return mod.outMod->GetOutputTime(); }
void setoutputtime(int time_in_ms) { }
void setvolume(int volume) { mod.outMod->SetVolume(volume); }
void setpan(int pan) { mod.outMod->SetPan(pan); }
int infoDlg(const char *fn, HWND hwnd)
{
return 0;
}
void getfileinfo(const char *filename, char *title, int *length_in_ms)
{
if (!filename || !*filename) filename=lastfn;
if (title)
{
const char *s=filename+7;
int n=0;
while (*s >= '0' && *s <= '9')
{
n*=10;
n += *s++ -'0';
}
sprintf(title,"%dhz Tone",n);
}
if (length_in_ms) *length_in_ms=-1000;
}
void eq_set(int on, char data[10], int preamp)
{
}
In_Module mod =
{
IN_VER,
L"Nullsoft Tone Generator v0.2 "
/* #ifdef __alpha
"(AXP)"
#else
"(x86)"
#endif */
,
0, // hMainWindow
0, // hDllInstance
"\0"
,
0, // is_seekable
1, // uses output
config,
about,
init,
quit,
getfileinfo,
infoDlg,
isourfile,
play,
pause,
unpause,
ispaused,
stop,
getlength,
getoutputtime,
setoutputtime,
setvolume,
setpan,
0,0,0,0,0,0,0,0,0, // vis stuff
0,0, // dsp
eq_set,
NULL, // setinfo
0 // out_mod
};
__declspec( dllexport ) In_Module * winampGetInModule2()
{
return &mod;
}
int _fltused=0;
DWORD WINAPI __stdcall PlayThread(void *b)
{
double angle=0.0,dangle=3.14159*2.0*(double)gen_freq/(double)44100.0;
while (! *((int *)b) )
{
if (mod.outMod->CanWrite() >= ((sizeof(sample_buffer)/2)<<(mod.dsp_isactive()?1:0)))
{
int l=sizeof(sample_buffer)/2,x=l/2;
short *s=sample_buffer;
while (x--)
{
int i;
double d = sin(angle)*32766.5;
#ifndef __alpha
__asm {
fld d
fistp i
}
#else
i = (int) d;
#endif
*s++=i;
angle += dangle;
}
{
int t=mod.outMod->GetWrittenTime();
mod.SAAddPCMData((char *)sample_buffer,1,16,t);
mod.VSAAddPCMData((char *)sample_buffer,1,16,t);
}
l=mod.dsp_dosamples(sample_buffer,l/2,16,1,44100)*2;
mod.outMod->Write((char *)sample_buffer,l);
}
else Sleep(50);
}
return 0;
}