0
0

Ok this works but the sound is played on half the speed.
I needed to do: FMOD->SetFrequency(fChannel, 88200) to get it wright

There’s also 1 buffer and that is not enough.

Got a little help from KarlKox, Brett & Gregggg… Thnx you guys.

I go on for a solution but any help would be apreciated

[code:16zihcm5]#include "in2.h" // the Winamp Input header file
typedef In_Module* (*pGetInModule)();
HMODULE wa_IN;
In_Module *InModule;
Out_Module *OutModule;
int srate, numchan, bps;
volatile int writtentime, w_offset;
static int last_pause=0;
FSOUND_STREAM *fStream;
int fChannel;
char *wabuffer;
int bufflength;
bool writebuf;

signed char FMODStreamCallback(FSOUND_STREAM *stream, void *buff, int len, int param)
{
if (bufflength == 0) return 0;

signed short *stereo16bitbuffer = (signed short *)buff;
signed short *wabuff = (signed short *)wabuffer;
memcpy(stereo16bitbuffer, wabuff, bufflength);

writebuf = true;
return 1;
}[/code:16zihcm5]

[code:16zihcm5]/***** Winamp Input plugin functions *****/

void SetInfo( int bitrate, int srate, int stereo, int synched ) {
// here you can specify various infos
}

void SAAddPCMData( void PCMData, int nch, int bps, int timestamp ) { / not needed */ }

int SAGetMode() {
return 1; /* must return 1 to say ok */
}

void SAAdd( void data, int timestamp, int csa) { / not needed */ }

void VSAAddPCMData( void PCMData, int nch, int bps, int timestamp ) { / not needed */ }

int VSAGetMode( int specNch, int *waveNch ) {
return 0; /
returning 0 mean, no pb */
}

void VSAAdd( void data, int timestamp ) { / not needed */ }

void VSASetInfo(int nch, int srate) { /* not needed */ }

int dsp_isactive() {
return 0; }

int dsp_dosamples( short int *samples, int numsamples, int bps, int nch, int srate ) {
return 0; }

void EQSet( int on, char data[10], int preamp) { /* not needed */ }

void _SAVSADeInit() { /* not needed */ }

void WMIN_SAVSAInit( int maxlatency_in_ms, int srate ) { /* not needed */ }[/code:16zihcm5]

[code:16zihcm5]/***** Winamp output plugin simulation *****/

void OutConfig(HWND hwnd) { /* not needed */ }

void OutAbout(HWND hwnd) { /* not needed */ }

void OutInit() { /* not needed */ }

void OutQuit() { /* not needed */ }

int OutOpen(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms)
{
writebuf = true;
srate = samplerate; // 44100 hz
numchan = numchannels; // 2 = stereo 1= mono
bps = bitspersamp; // 16 bit or 8 bit
fStream = FMOD->FSOUND_Stream_Create(FMODStreamCallback, 576numchan(bps/8)*2, FSOUND_NORMAL, srate, 12345);
fChannel = FMOD->FSOUND_Stream_Play(FSOUND_FREE, fStream);
return 50; // return latency time
}

void OutClose() { /* close it */ }

int OutWrite(char *buf, int len)
{

bufflength = len;
if (len >0) wabuffer = buf;
else FMOD->FSOUND_Stream_Stop(fStream);

writebuf = false;
Sleep(0);
return 0;
// 0 on success. Len == bytes to write (<= 8192 always). buf is straight audio data.
// 1 returns not able to write (yet). Non-blocking, always.
}

int OutCanWrite()
{
// return the current buffersize (the one allocated by fmod for example)
if (writebuf) return last_pause?0:576numchan(bps/8)*2;
else return 0;
}

int OutIsPlaying()
{
// non0 if output is still going or if data in buffers waiting to be
// written (i.e. closing while IsPlaying() returns 1 would truncate the song /*
return 0;
}

int OutPause(int pause)
{
FMOD->FSOUND_SetPaused(fChannel, (bool)pause);
int t=last_pause;
last_pause=pause;
// return previous pause state
return t;
}

void OutSetVolume(int volume) { /* not needed / }
void OutSetPan(int pan) { /
not needed */ }

void OutFlush(int t)
{
// flushes buffers and restarts output at time t (in ms)
}

int OutGetOutputTime() { return 0; /* not needed ? */ }

int OutGetWrittenTime()
{
// wa_in uses this in a calculation to get exact: getoutputtime()
return 0;
}[/code:16zihcm5]

[code:16zihcm5]void SetItUpClick()
{
OutModule = new Out_Module;
OutModule->version = 0;
OutModule->description = “FMOD Out Plugin emulator”;
OutModule->id = 33;
OutModule->Config = OutConfig;
OutModule->About = OutAbout;
OutModule->Init = OutInit;
OutModule->Quit = OutQuit;
OutModule->Open = OutOpen;
OutModule->Close = OutClose;
OutModule->Write = OutWrite;
OutModule->CanWrite = OutCanWrite;
OutModule->IsPlaying = OutIsPlaying;
OutModule->Pause = OutPause;
OutModule->SetVolume = OutSetVolume;
OutModule->SetPan = OutSetPan;
OutModule->Flush = OutFlush;
OutModule->GetOutputTime = OutGetOutputTime;
OutModule->GetWrittenTime = OutGetWrittenTime;

if (wa_IN == NULL) {
wa_IN = LoadLibrary(“in_mp3.dll”); // Load a winamp Input plugin
if (wa_IN != NULL) {
// Now get the Process Address
pGetInModule GetInModule = (pGetInModule) GetProcAddress(wa_IN, “winampGetInModule2”);
// Now get the module of the plugin
InModule = GetInModule();
GetInModule = NULL;
if (InModule != NULL) {
InModule->hMainWindow = Application->Handle; // The handle of the mainwindow
InModule->hDllInstance = wa_IN; // Handle to this DLL
InModule->Init(); // Initialize the module

          InModule-&gt;SetInfo = SetInfo;
          InModule-&gt;SAAddPCMData = SAAddPCMData;
          InModule-&gt;SAGetMode = SAGetMode;
          InModule-&gt;SAAdd = SAAdd;
          InModule-&gt;VSAAddPCMData = VSAAddPCMData;
          InModule-&gt;VSAGetMode = VSAGetMode;
          InModule-&gt;VSAAdd = VSAAdd;
          InModule-&gt;VSASetInfo = VSASetInfo;
          InModule-&gt;dsp_isactive = dsp_isactive;
          InModule-&gt;dsp_dosamples = dsp_dosamples;
          InModule-&gt;EQSet = EQSet;
          InModule-&gt;SAVSADeInit = _SAVSADeInit;
          InModule-&gt;SAVSAInit = WMIN_SAVSAInit;
          InModule-&gt;outMod = OutModule;
      }
  }

}
}[/code:16zihcm5]

  • You must to post comments
0
0

While using the pitch function in FMOD i found out that the buffersize of 4608 is to small to use.
So in FSOUND_Stream_Create i set the buffersize to 9216 and that worked fine.

But now there’s another problem. When i minimize or maximize a window FMOD stops playing, and i can’t figure out why. It happens in Winmm, directsound and asio.

Also the player stutters when i open/close a app, but that was solved by giving the app “realtime” priority.

B.t.w. I use Win 2k

  • You must to post comments
0
0

Well made a sample app so you can here which problems occure.

[url:23lzfixs]http://www.mp3tunes.nl/test.rar[/url:23lzfixs]

  • First hit the [Load it] button to initialize FMOD and the Out_Module
  • Then hit [Load in_mp3] to load the winamp input plugin
  • Enter a full path to a mp3 in the editbox and hit [Load Song] to play the file.
  • Use the slidebar in the bottom to change the pitch

Now you can hear and see what problems occure.
Also if you load a 22050 Hz song you see the winamp buffersize is devided by 2.
So I made another example prog which had a larger buffer and filled that with winamp buffers and when fmod needed some data i moved it to the FMOD buffer, that sounded good!
The changes i made will be available soon ๐Ÿ˜€

  • You must to post comments
0
0

Modified the sample app so you can here which problems occure.
Also the BCB source in included but without my FMOD component !!!!
So it won’t work if you compile it unless you make your own.

[url:2kisf123]http://www.mp3tunes.nl/test.rar[/url:2kisf123]

  • First hit the [Load it] button to initialize FMOD and the Out_Module
  • Then hit [Load in_mp3] to load the winamp input plugin
  • Enter a full path to a mp3 in the editbox and hit [Load Song] to play the file, or hit [Song info] to show the internal id3 tagger.
  • Use the slidebar in the bottom to change the pitch (22050 – 66150)

The rest of the buttons speak for them selves ๐Ÿ˜‰

  • You must to post comments
0
0

That i didn’t see that before ๐Ÿ˜ณ

I use:
[code:qppsmr2k]fStream = FMOD->FSOUND_Stream_Create(streamcallback, 576numchan(bps/8 )*2, FSOUND_NORMAL, srate, 12345);[/code:qppsmr2k]

But i needed to do this:
[code:qppsmr2k]fStream = FMOD->FSOUND_Stream_Create(streamcallback, 576numchan(bps/8 )*2, FSOUND_NORMAL | FSOUND_16BITS | FSOUND_STEREO, srate, 12345);[/code:qppsmr2k]

Thanx brett,

FMOD RULEZZZZ now i can use almost every winamp input plugin ๐Ÿ˜€

  • You must to post comments
0
0

Well tried to use multiple input plugins but that won’t work simultanious ๐Ÿ˜ฅ

The in2.h and out.h of winamp have structures with static functions, and static functions can only be made once ๐Ÿ˜ฅ

If someone knows how to get around this please tell it here !!!!!!

Did found some info here [url:1wmyzhuq]http://www.codeproject.com/useritems/Delegate_to_callback.asp[/url:1wmyzhuq] but couldn’t understand it yet

[url:1wmyzhuq]http://ftpwa.newaol.com/customize/component/nsdn/winamp2x/in_minisdk.zip[/url:1wmyzhuq]

WAOUT.H
[code:1wmyzhuq]#ifndef WAOUT_H

define WAOUT_H

include <windows.h>

include "in2.h"

define wabufsize 27648

// these functions are static and work :)
void OutConfig(HWND hwnd) { /* not needed / }
void OutAbout(HWND hwnd) { /
not needed / }
void OutInit() { /
not needed / }
void OutQuit() { /
not needed / }
void OutClose() { /
close it / }
void OutSetVolume(int volume) { /
not needed / }
void OutSetPan(int pan) { /
not needed / }
int OutGetOutputTime() { return 0; /
not needed ? */ }

class WAOutMod {
private:
// Some private declarations ?
// hmm you may use everything :)
public:
Out_Module* Create(void);

// These functions are not static and don’t work :(
int OutOpen(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms);
int OutWrite(char *buf, int len);
int OutCanWrite();
int OutIsPlaying();
int OutPause(int pause);
void OutFlush(int t);
int OutGetWrittenTime();

    Out_Module *OutModule;
    char wabuffer[wabufsize];
    int  buffcount;
    int  bufferlength;
    int  samplerate;
    int  numchannels;
    int  bitspersamp;
    int  last_pause;

};

endif[/code:1wmyzhuq]

WAOUT.CPP
[code:1wmyzhuq]#include “waout.h”

Out_Module* WAOutMod::Create()
{
OutModule = new Out_Module;
OutModule->version = 0;
OutModule->description = “FMOD Winamp Out Plugin emulator”;
OutModule->id = 33;
OutModule->Config = OutConfig;
OutModule->About = OutAbout;
OutModule->Init = OutInit;
OutModule->Quit = OutQuit;
OutModule->Open = OutOpen; // compile error here
// Error Message: Member function must be called or its address taken.

OutModule->Close = OutClose;
OutModule->Write = this->OutWrite; // compile error here
OutModule->CanWrite = this->OutCanWrite; // compile error here
OutModule->IsPlaying = this->OutIsPlaying; // compile error here
OutModule->Pause = this->OutPause; // compile error here
OutModule->SetVolume = OutSetVolume;
OutModule->SetPan = OutSetPan;
OutModule->Flush = this->OutFlush; // compile error here
OutModule->GetOutputTime = OutGetOutputTime;
OutModule->GetWrittenTime = this->OutGetWrittenTime; // compile error here
return OutModule;
}

int WAOutMod::OutOpen(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms)
{
buffcount = 0;
samplerate = samplerate; // 44100 hz
numchannels = numchannels; // 2 = stereo 1= mono
bitspersamp = bitspersamp; // 16 bit or 8 bit
return 50; // return latency time
}

int WAOutMod::OutWrite(char buf, int len)
{
// here you will write your data to the *buf param, it must be fast and efficient
if (buffcount
len+len <= wabufsize && len > 0) {
bufferlength = len;
memcpy(wabuffer+(buffcount*len), buf, len);
buffcount++;
}
else return 1;

Sleep(0);
return 0;
// 0 on success. Len == bytes to write (<= 8192 always). buf is straight audio data.
// 1 returns not able to write (yet). Non-blocking, always.
}

int WAOutMod::OutCanWrite()
{
// return the current buffersize (the one allocated by fmod for example)
if (buffcountbufferlength+bufferlength <= wabufsize)
return last_pause?0:576
numchannels(bitspersamp/ 8 )2;
else return 0;
}

int WAOutMod::OutIsPlaying()
{
// non0 if output is still going or if data in buffers waiting to be
// written (i.e. closing while IsPlaying() returns 1 would truncate the song /*
return 0;
}

int WAOutMod::OutPause(int pause)
{
int t = last_pause;
last_pause = pause;
// return previous pause state
return t;
}

void WAOutMod::OutFlush(int t)
{
// flushes buffers and restarts output at time t (in ms)
}

int WAOutMod::OutGetWrittenTime()
{
// wa_in uses this in a calculation to get exact: getoutputtime()
return 0;
}[/code:1wmyzhuq]

  • You must to post comments
0
0

Maybe i gonna use it, if it’s stable because:

Why invent a file decoder if it already exist

  • You must to post comments
0
0

i ve coded a simple app wich can handle multiple input with your code, if you can wait until this week end, i ll try to add the code in my dll wrapper and update the VB sample app, so stay tune :)

  • You must to post comments
0
0

brett>he want to do a winamp input wrapper, it is not for the wa DSP ๐Ÿ˜€

  • You must to post comments
0
0

OK thnx

  • You must to post comments
0
0

i say that ‘coze i ve released a sourcecode of a dll for dsp/vis winamp support for fmod (with a vb sample) :)

source :

http://starnetasso.free.fr/Upload/fmodW … insSrc.rar

binary:

http://starnetasso.free.fr/Upload/VisWinampTest.rar

(rar 3.x)

  • You must to post comments
0
0

Yep and now there’s also one for the input plugins ๐Ÿ˜€

Shall release it shortly

  • You must to post comments
0
0

i know that but i really have enough time to do it … perhaps releasing the sourcecode of your sample will help me to find the motivation :)

  • You must to post comments
0
0

This code works almost perfectly.
You can even change the buffersize of FMOD but watchout that wabuffer >= the FMOD buffer.

This is not all the code !!!!, also see above the setitupclick function.
Mention that i used OutModule = new Out_Module;
That is the calloc function in Borland C++ Builder

[code:30hilg6y]#include "in2.h"

define wabufsize 27648

char wabuffer[wabufsize];
int bufflength;
int memcount;
typedef In_Module* (*pGetInModule)();
HMODULE wa_IN;
In_Module *InModule;
Out_Module *OutModule;
int srate, numchan, bps;
static int last_pause=0;
FSOUND_STREAM *fStream;
int fChannel;

/***************************/
/*** FMOD StreamCallback ***/
/***************************/
signed char streamcallback(FSOUND_STREAM *stream, void *buff, int len, int param)
{
if (bufflength == 0) return 0;

if (memcount <= -1+(len/bufflength)) {
FMOD->FSOUND_Stream_Stop(fStream);
return 0;
}
memcpy(buff, wabuffer, len);
memmove(wabuffer, wabuffer+len, bufflength*memcount-len);
memcount -= len/bufflength;

return 1;
}

/************************************/
/*** WINAMP Input plugin functions***/
/************************************/

void SetInfo( int bitrate, int srate, int stereo, int synched ) {
if (srate > 0) {
// Set some info labels here
}
}
void SAAddPCMData( void PCMData, int nch, int bps, int timestamp ) { / not needed / }
int SAGetMode() { return 1; /
must return 1 to say ok / }
void SAAdd( void *data, int timestamp, int csa) { /
not needed / }
void VSAAddPCMData( void *PCMData, int nch, int bps, int timestamp ) { /
not needed / }
int VSAGetMode( int *specNch, int *waveNch ) { return 0; /
returning 0 mean, no pb / }
void VSAAdd( void *data, int timestamp ) { /
not needed / }
void VSASetInfo(int nch, int srate) { /
not needed / }
int dsp_isactive() { return 0; }
int dsp_dosamples( short int *samples, int numsamples, int bps, int nch, int srate ) { return 0; }
void EQSet( int on, char data[10], int preamp) { /
not needed / }
void _SAVSADeInit() { /
not needed / }
void WMIN_SAVSAInit( int maxlatency_in_ms, int srate ) { /
not needed */ }

/********************************/
/*** WINAMP Output simulation ***/
/********************************/

void OutConfig(HWND hwnd) { /* not needed / }
void OutAbout(HWND hwnd) { /
not needed / }
void OutInit() { /
not needed / }
void OutQuit() { /
not needed */ }

int OutOpen(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms)
{
memcount = 0;
srate = samplerate; // 44100 hz
numchan = numchannels; // 2 = stereo 1= mono
bps = bitspersamp; // 16 bit or 8 bit

Form1->Label1->Caption = srate;
Form1->Label2->Caption = numchannels;
Form1->Label3->Caption = bitspersamp;

fStream = FMOD->FSOUND_Stream_Create(streamcallback, 576numchan(bps/8)2, FSOUND_NORMAL | FSOUND_16BITS | FSOUND_STEREO, srate, 12345);
fChannel = FMOD->FSOUND_Stream_Play(FSOUND_FREE, fStream);
return 50; // return latency time
}
void OutClose() { /
close it / }
int OutWrite(char *buf, int len)
{
if (memcount
len+len <= wabufsize && len > 0) {
bufflength = len;
memcpy(wabuffer+(memcount*len), buf, len);
memcount++;
}
else return 1;

return 0;
// 0 on success. Len == bytes to write (<= 8192 always). buf is straight audio data.
// 1 returns not able to write (yet). Non-blocking, always.
}
int OutCanWrite()
{
// return the current buffersize (the one allocated by fmod for example)
if (memcountbufflength+bufflength <= wabufsize) return last_pause?0:576numchan(bps/8)2;
else return 0;
}
int OutIsPlaying()
{
// non0 if output is still going or if data in buffers waiting to be
// written (i.e. closing while IsPlaying() returns 1 would truncate the song
return 0;
}
int OutPause(int pause)
{
FMOD->FSOUND_SetPaused(fChannel, (bool)pause);
int t=last_pause;
last_pause=pause;
// return previous pause state
return t;
}
void OutSetVolume(int volume) { /* not needed / }
void OutSetPan(int pan) { /
not needed / }
void OutFlush(int t)
{
// flushes buffers and restarts output at time t (in ms)
}
int OutGetOutputTime() { return 0; /
not needed ? */ }
int OutGetWrittenTime()
{
// wa_in uses this in a calculation to get exact: getoutputtime()
return 0;
}[/code:30hilg6y]

  • You must to post comments
0
0

mmhh when i said to release the sourcecode, it is not in this way but in a zip file with your project/files/etc … :)

  • You must to post comments
0
0

Well that’s a little difficult.

I use Borland C++ Builder 4 and made a VCL project of it.
Also i use a own made VCL component which controls FMOD.

So in fact if you don’t use BCB then it’s a problem to view the source.

B.t.w. It only loads 1 plugin for now, and it’s not a DLL yet.

With the above code you can make your own, there’s nothing hidden.

  • You must to post comments
Showing 15 results
Your Answer

Please first to submit.