Author Topic: wasapi c++ problem  (Read 2420 times)

horneff

  • Posts: 5
wasapi c++ problem
« on: 3 Feb '14 - 06:53 »
How to encode wasapi data to wav file? Here is my code:

Code: [Select]
if (BASS_WASAPI_Init(11, 0, 0, 0, 0.4, 0.05, OutWasapiProc, NULL)) {
BASS_WASAPI_INFO wi;
BASS_WASAPI_GetInfo(&wi);
instream = BASS_StreamCreate(wi.freq, wi.chans, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE, STREAMPROC_PUSH, NULL);
hencode=BASS_Encode_Start(instream, "output.wav", BASS_ENCODE_PCM, NULL, 0);
BASS_WASAPI_Start();
}

DWORD CALLBACK OutWasapiProc(void *buffer, DWORD length, void *user)
{
BASS_StreamPutData(instream, buffer, length);

return 1;
}

but it produces 0 bytes wav file only. How to made it work?

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: wasapi c++ problem
« Reply #1 on: 3 Feb '14 - 15:40 »
The problem there is that the data is left sitting in the "push" stream's buffer; there are BASS_StreamPutData calls to put data in the stream but no BASS_ChannelGetData calls to take it out. Rather than a push stream, I would suggest using a "dummy" stream for this sort of thing, like this...

Code: [Select]
if (BASS_WASAPI_Init(11, 0, 0, 0, 0.4, 0.05, OutWasapiProc, NULL)) {
BASS_WASAPI_INFO wi;
BASS_WASAPI_GetInfo(&wi);
instream = BASS_StreamCreate(wi.freq, wi.chans, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE, STREAMPROC_DUMMY, NULL); // create a dummy stream
hencode=BASS_Encode_Start(instream, "output.wav", BASS_ENCODE_PCM, NULL, 0);
BASS_WASAPI_Start();
}

DWORD CALLBACK OutWasapiProc(void *buffer, DWORD length, void *user)
{
BASS_ChannelGetData(instream, buffer, length); // pass the captured data through the dummy stream

return 1;
}

A dummy stream provides no data itself, so the encoder set on it receives the data in the buffer that you provide in the BASS_ChannelGetData call.

horneff

  • Posts: 5
Re: wasapi c++ problem
« Reply #2 on: 4 Feb '14 - 03:34 »
Thanks. Another question. How convert wasapi stream to 44100 2 channels stereo for example? wasapi stream may be any sample rate from (8000...192000) and any channels from (1...8). And how BASS mix 5.1 to 2.0? In the help there written that only LEFT and RIGHT channels mix and other channels are out. Is it true?

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: wasapi c++ problem
« Reply #3 on: 4 Feb '14 - 15:40 »
The BASSmix add-on can be used to convert the sample format, eg. create a mixer with the target format via BASS_Mixer_StreamCreate and plug the source stream ("instream") into that via BASS_Mixer_StreamAddChannel. Please see the RECTEST example included in the BASSWASAPI package for a demonstration. You can use the BASS_MIXER_DOWNMIX flag in the BASS_Mixer_StreamAddChannel call to have multi-channel data downmixed to stereo or mono. Note you will need to switch back to using a "push" stream (as in the RECTEST example), as a "dummy" stream can't feed a mixer.

horneff

  • Posts: 5
Re: wasapi c++ problem
« Reply #4 on: 5 Feb '14 - 04:21 »
Thanks. It works, but some problem with 5.1, there is no downmix of Back Left and Back Right. How mix it to like this?

L_out = L*0.314 + C*0.222 + LFE*0.031 + BL*0.268 + BR*0.164
R_out = R*0.314 + C*0.222 + LFE*0.031 + BL*0.164 + BR*0.268

Also with 7.1 same problem?

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: wasapi c++ problem
« Reply #5 on: 7 Feb '14 - 15:47 »
If you would like to apply your own downmixing matrix, you can do so via BASS_Mixer_ChannelSetMatrix. For example, to apply the matrix above, you would do this...

Code: [Select]
float matrix[2][6]={ // 2 outputs, 6 inputs
    {0.314, 0, 0.222, 0.031, 0.268, 0.164}, // left out
    {0, 0.314, 0.222, 0.031, 0.164, 0.268} // right out
};
BASS_Mixer_ChannelSetMatrix(handle, matrix); // apply the matrix

Please see the "Matrix mixing" section of the BASSmix documentation for details. For 8 input channels, you would simply increase the array's dimensions to include the 2 extra channels.

horneff

  • Posts: 5
Re: wasapi c++ problem
« Reply #6 on: 9 Feb '14 - 10:40 »
Ok. How to remove memory leak from BASS_StreamPutData? I made BASS_ChannelSetPosition but sound becomes to record faster and with clicks. Is BASS has another way to clear stream buffer? Here is the code:

Code: [Select]
DWORD CALLBACK InWasapiProc(void *buffer, DWORD length, void *user)
{
...
int putout = BASS_StreamPutData(instream, buffer, length); // memory leak
int c = BASS_ChannelGetData(outmixer, mixbuffer, mixlength);

        //BASS_ChannelSetPosition(instream, 0, BASS_POS_BYTE); //if this is present than no memory leak but problem the faster sound recording
        //BASS_ChannelPlay(instream, true); //memory leak too
...
}
« Last Edit: 9 Feb '14 - 11:17 by horneff »

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: wasapi c++ problem
« Reply #7 on: 10 Feb '14 - 17:41 »
When you're using a mixer for resampling and encoding, to ensure that all of the source data is processed, you can repeatedly call BASS_ChannelGetData until the mixer produces no more data. For example, like this...

Code: [Select]
DWORD CALLBACK InWasapiProc(void *buffer, DWORD length, void *user)
{
...
BASS_StreamPutData(instream, buffer, length);
while (1) {
int got=BASS_ChannelGetData(outmixer, buffer, length);
if (got<=0) break; // no more data to process (or an error)
}
...
}

horneff

  • Posts: 5
Re: wasapi c++ problem
« Reply #8 on: 14 Feb '14 - 12:16 »
Thanks
« Last Edit: 14 Feb '14 - 13:00 by horneff »