Author Topic: Play selected mic input directly through to output  (Read 2078 times)

sfree82

  • Posts: 2
I have an existing application that now requires the sound from a USB microphone to be streamed directly to the output of the same machine.

I have tried using the sample code based on the LiveFX sample which creates a Push stream, starts a recording with a callback, puts the data based on this call back to the stream to play.  This seems to work fine but in some instances I am getting choppy / stutter on the playback.

I've searched the forums and found this suggestion on this thread http://www.un4seen.com/forum/?topic=9943.msg69190#msg69190 which suggests not using a callback on the recording.

Quote
However, a PUSH stream might actually not be needed.
You might simply create a recording stream without ANY RECORDPROC, e.g.:

Code: [Select]
_recordStream = BASS_RecordStart(44100, 2, BASSFlag.BASS_SAMPLE_FLOAT, null, IntPtr.Zero);
And add this '_recordStream' directly to the mixer as a source.

I don't need to perform any effects or processing on the audio so this looks like it could be the way to go, however I can't seem to get it to work.  I've tried using the BASS_StreamCreateFile function with mem=TRUE and passing it the returned handle of the RecordStart function but I'm not even sure if this is the correct method.

I'm using Bass v2.4.5 on Windows 7 32 bit (testing as well on XP 32 bit), existing code is unfortunately VB6 but I'm more than happy to get this functioning in C++ or Delphi if the problem is associated with performance issues in VB6.

Any help from an audio Jedi much appreciated...

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: Play selected mic input directly through to output
« Reply #1 on: 5 May '10 - 15:29 »
In that other thread, a recording channel was feeding a mixer, and that could be done by plugging the recording channel directly into the mixer (by not using a RECORDPROC to make it a "decoding channel") without the need for a "push" stream in between.

In your case, it sounds like a more straightforward case of the output stream running out of data to play, and simply waiting a bit longer before starting the output could help. Are you able to reproduce the problem with the LIVEFX example itself? If that is fine, check that you have included the "prebuffer at least minbuf amount of data before starting playback" stuff in your app (note that also requires the use of the BASS_DEVICE_LATENCY flag).

sfree82

  • Posts: 2
Re: Play selected mic input directly through to output
« Reply #2 on: 5 May '10 - 15:37 »
Hi Ian, thanks for the info

The code I have implemented is pretty much the same as the LiveFX demo but with extra code to allow user selection of the input and output device to use.  I've double checked and it does have BASS_DEVICE_LATENCY flag on init and the prebuf loop (I've also added a time out of 5 seconds as this occasionally ran forever - could this indicate that the input failed?)

Further investigation has revealed some odd behaviour.

In the LiveFX demo code the app initialises recording using the default input device.

Code: [Select]
// start recording with 10ms period
if (!BASS_RecordInit(-1) || !(rchan=BASS_RecordStart(44100,2,MAKELONG(0,10),RecordingCallback,0))) {

In my use of this code I have altered the call to BASS_RecordInit from -1 to be the index of the device that I want to use, when I do this it introduces the choppy playback even if I am using the same device as denoted by default

i.e. BASS_RecordInit(-1) and BASS_RecordInit(0) use the same device but the former has smooth playback and the latter introduces the stuttering.... very strange (and BASS_RecordInit(1) is also choppy)

Also if I alter the code in the LiveFX demo to use BASS_RecordInit(0), recompile and run I get the same choppy playback in both the C++ and VB6 LiveFX demo apps.

Any idea why this might cause an issue?

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: Play selected mic input directly through to output
« Reply #3 on: 5 May '10 - 17:53 »
In my use of this code I have altered the call to BASS_RecordInit from -1 to be the index of the device that I want to use, when I do this it introduces the choppy playback even if I am using the same device as denoted by default

i.e. BASS_RecordInit(-1) and BASS_RecordInit(0) use the same device but the former has smooth playback and the latter introduces the stuttering.... very strange (and BASS_RecordInit(1) is also choppy)

Also if I alter the code in the LiveFX demo to use BASS_RecordInit(0), recompile and run I get the same choppy playback in both the C++ and VB6 LiveFX demo apps.

That is indeed very strange. When device=-1 is used, BASS_RecordInit will check which device is the default, and that will then be initialized just as if it had been specified in the call itself. So if you are seeing a difference between using the default device's number or -1, I think it would have to be a coincidence.

For some info on the problem, how much data is being received in each call of the RECORDPROC? Also, if you add this after the pre-buffering loop in the LIVEFX example...

Code: [Select]
{
DWORD avail=BASS_ChannelGetData(chan,NULL,BASS_DATA_AVAILABLE);
// set a breakpoint here
BASS_ChannelPlay(chan,FALSE);
}

What value do you get for "avail" in each case? Also, what value do you get in "bi.minbuf"?

Does the problem only happen when using the USB microphone, or does it apply to other recording devices too? Also, what is the output device, and does changing that make any difference?