20 Jun '13 - 09:45 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]
  Reply  |  Print  
Author Topic: Exporting to wave  (Read 1318 times)
neurasthenik
Posts: 17


« on: 1 Dec '09 - 22:15 »
Reply with quoteQuote

Hello. I wrote some kind of drum machine, which was using BASS library. I would like to export the drum samples into WAV file, including the intervals, mixing the samples, etc. Obviously the drum track is being held in buffer (two dimensional array) and so the intervals (simple array).  What would be the best solution to do it?
Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #1 on: 2 Dec '09 - 14:51 »
Reply with quoteQuote

How are you playing the drum samples? If you're using a mixer (BASSmix add-on), then it would simply be a matter of using the BASSenc add-on to attach an encoder (or WAV writer) to the mixer via BASS_Encode_Start.
Logged
neurasthenik
Posts: 17


« Reply #2 on: 2 Dec '09 - 15:21 »
Reply with quoteQuote

I'm simply using timeSetEvent timer and playing streams by BASS_ChannelPlay.
Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #3 on: 2 Dec '09 - 16:58 »
Reply with quoteQuote

OK. In that case, you could use the recording functions to capture the mix (eg. with the "Stereo Mix" input), but that will capture the output from other processes too. Perhaps you could modify your app to use a mixer instead? That would also have the advantage of more precise timing, eg. you can set the drum positions to the exact byte.

To trigger a drum, you would set a mixtime POS sync on the mixer at the wanted position, and then add the drum to the mixer in the SYNCPROC. It could look something like this...

typedef structure {
float time; // start time in seconds
HSTREAM handle; // stream to play (must be a decoding channel - see BASS_STREAM_DECODE)
} event;

event events[num_events]; // array of events

...

mixer=BASS_Mixer_StreamCreate(...); // create the mixer

// set a sync to trigger each event
for (n=0; n<num_events; n++) {
QWORD syncpos=BASS_ChannelSeconds2Bytes(mixer, events[n].time); // convert seconds to bytes
BASS_ChannelSetSync(mixer, BASS_SYNC_POS|BASS_SYNC_MIXTIME, syncpos, TriggerSyncProc, (void*)n); // set a mixtime POS sync there
}

...

void CALLBACK TriggerSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user)
{
int n=(int)user; // event number
BASS_ChannelSetPosition(events[n].handle, 0, BASS_POS_BYTE); // rewind the stream (eg. in case it has already been played)
BASS_Mixer_StreamAddChannel(mixer, events[n].handle, 0); // add it to the mixer
}
Logged
neurasthenik
Posts: 17


« Reply #4 on: 3 Dec '09 - 20:40 »
Reply with quoteQuote

Actually I've chosen the first solution, recording the .wav file in the real time. I used a following code, basing on BASS 2.3 help:


FILE *msfile;
msfile = fopen("1.wav", "w");

BOOL CALLBACK MyRecordingWriter(HRECORD handle, void *buf, DWORD len, DWORD user)
{
    fwrite(buf,1,len,msfile); // write the buffer to the file
    return TRUE; // continue recording
}

HRECORD record=BASS_RecordStart(44100,2,0,&MyRecordingWriter,0); // start recording


It creates the .wav file. but there's nothing in it, the file has 0 kb...
Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #5 on: 4 Dec '09 - 15:58 »
Reply with quoteQuote

That looks like the BASS_RecordStart call failed; what is the return value? If 0, you can then call BASS_ErrorGetCode to find out why it failed.

Btw, that code won't create a valid WAV file, as it is missing a WAVE header. A simpler way to do that would be with the BASSenc add-on (see BASS_Encode_Start).
Logged
neurasthenik
Posts: 17


« Reply #6 on: 4 Dec '09 - 18:28 »
Reply with quoteQuote

Thanks for your reply Ian! Cheesy  I handled it using the following BCB code:


HRECORD record;

BOOL CALLBACK RecordProc(HRECORD handle, const void *buf, DWORD len, DWORD user);

//...

void __fastcall TForm1::Button1Click(TObject *Sender)
{
        record = BASS_RecordStart(44100, 2, 0, &RecordProc, 0);

        BASS_Encode_Start(record,"output.wav",BASS_ENCODE_PCM,NULL,0);
        BASS_ChannelPlay(record, 0);
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button2Click(TObject *Sender)
{
        BASS_Encode_Stop(record);
        BASS_ChannelStop(record);
}

/******************************************************************************/

BOOL CALLBACK RecordProc(HRECORD handle, const void *buf, DWORD len, DWORD user)
{
return TRUE; // continue recording
}


Everything works OK now !
« Last Edit: 4 Dec '09 - 20:06 by neurasthenik » Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines