0
0

I am trying to build a real-time application that analyzes an audio-stream similar to the pitch detection example. Therefore I reused this code, but there seems to be a delay up to some 3 secs. when playing the incoming steam. Since the sound should be played in real-time I need the delay to be as small as possible.

Any ideas what I can do about this?

Thanks in advance!

  • You must to post comments
0
0

The pitch detection example uses getSpectrum which analyses all the data leading up to now. The way this works is a bigger FFT window will create more ‘lag’. You can reduce the window size by reducing the ‘numvalues’. There is more information available in the Channel::getSpectrum section of fmodex.chm.

  • You must to post comments
0
0

I also thought getSpectrum may cause the delay, so I commented it out and the delay is still about the same.

  • You must to post comments
0
0

Mic has always been a problem (Vista 64 for me)… the closest I managed to fix this was do something like
1) create the stream, possibly set volume to 0
2) system update a few second
3) <volume back to 1> call set position to that few seconds – 100 to 200 ms

ready.

also, I have trouble when I create another stream, later, in subsequent execution. you hear in the background, for the duration of the buffer, the previous recording, faintly. The only way to clear that is to reboot the pc

  • You must to post comments
0
0

which parameters should I use for setPosition?
should I call system->update() also, while I call setPosition for some seconds?

  • You must to post comments
0
0

[quote="AudioGuy":2id4dj25]which parameters should I use for setPosition?
should I call system->update() also, while I call setPosition for some seconds?[/quote:2id4dj25]

Looking at my code (It’s split between 2 file, my dll and caller)

It looks like this if I did not loose any important information
Start Recording
Set volume 0
Sleep 200 ms
System Update
SetPosition in ms at 28 ms…
Set volume 1
System Update
I think that was the closest I was able to make it to be live. without the whole thing freaking out on me in one way ore another. 172 ms behind.

Also, you need a headset with mic or else, with volume 1, you get feedback on my setup even with the supplied demo, turning the volume on. It was a while back since I did this. I forgot most of what I did back then. I dont think the volume mutes the input at the mic, it’s to prevent initial noise at the speaker when you start recording and to prevent feedback (in the demo)….

  • You must to post comments
0
0

I tried this, but it didn’t show any effect.. the delay is still there.

Any other ideas what I can do about it?
(worst case: which other libraries could I use?)

  • You must to post comments
0
0

To get the minimal recording latency do the following:

  1. Determine your desired latency, i.e. 30ms, you can tweak this until recording / playback is stable.
  2. Start the recording.
  3. In a loop check the record head position with System::getRecordPosition and sleep for 1ms until you reach your desired latency (30ms from above). Don’t rely on sleep being accurate, always measure the latency with the record position.
  4. Now play the recording sound from the start. You can use Channel::getPosition and System::getRecordPosition to monitor any fluctuations.
  5. Optional if there is fluctuation you can correct it by very slightly modifying the playback frequency of the channel, so small that you won’t hear the pitch difference, but enough to consume the data slower / faster as required to re-stabilize the distance between recording and reading positions.

Other things to consider are "bufferlength" and "numbuffers" from System::getDSPBufferSize. Data from the mic will be mixed into the output stream for playback every "bufferlength" samples. And you won’t hear that output until the whole output buffer has been consumed, so "numbuffers" * "bufferlength" worth of samples. You can tweak these values to reduce latency on output (be wary of introducing instability in the output though).

Also be aware that different output modes introduce different latencies, I would recommending just using the default for your platform though.

I hope this helps clarify recording issues, let me know if you have any issues / questions.

  • You must to post comments
0
0

In case it is of relevance, I’m using a USB Guitar Interface for recording. Also I noticed when I start recording there is almost no delay for about 2 seconds. Then I always hear a noise and afterwards everything gets delayed.

Anyway, here is my code since I’m not sure how to check for latency by using getRecordPosition.

This is the main loop:
[code:2v7zl7oj]
stream = new AudioStream(44100, 2048, FMOD_OUTPUTTYPE_ASIO);

stream-&gt;start(); 
stream-&gt;setVolume(100); 

while(true)
{
    stream-&gt;update(); 
    Sleep(10); 
}  

stream-&gt;close();

[/code:2v7zl7oj]

This is my AudioStream class. The code is basically the same as one of the FMOD examples.

[code:2v7zl7oj]
AudioStream::AudioStream(int sampleRate, int spectrumSize, FMOD_OUTPUTTYPE outputType, FMOD_SOUND_FORMAT soundFormat)
{
...
init();
}

void AudioStream::init()
{
if(system != 0) close();

FMOD_RESULT result; 
result = FMOD::System_Create(&amp;system); 
errorCheck(result); 

unsigned int version; 
result = system-&gt;getVersion(&amp;version); 
errorCheck(result); 

if(version &lt; FMOD_VERSION)
{
    throw &quot;Error! You are using an old version of FMOD!&quot;;
}
else
{
    result = system-&gt;setOutput(outputType); 
    errorCheck(result); 
}

}

void AudioStream::start()
{
FMOD_RESULT result;

result = system-&gt;setDriver(playbackDriver);
errorCheck(result); 

result = system-&gt;setSoftwareFormat(sampleRate, soundFormat, 1, 0, FMOD_DSP_RESAMPLER_LINEAR);
errorCheck(result); 

result = system-&gt;init(1, FMOD_INIT_WASAPI_EXCLUSIVE /*FMOD_INIT_NORMAL*/, 0); 
errorCheck(result); 

//create a sound to record to

FMOD_CREATESOUNDEXINFO exinfo;
memset(&amp;exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); 

exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO); 
exinfo.numchannels      = 1; 
exinfo.format           = soundFormat; 
exinfo.defaultfrequency = sampleRate; 
exinfo.length           = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 5;

result = system-&gt;createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_LOOP_NORMAL | FMOD_OPENUSER, &amp;exinfo, &amp;sound); 

errorCheck(result);

//start the interface

result = system-&gt;recordStart(recordDriver, sound, true);
errorCheck(result);

Sleep(200); 

result = system-&gt;playSound(FMOD_CHANNEL_FREE, sound, false, &amp;channel);
errorCheck(result); 

}

void AudioStream::update()
{
if(system != 0)
{
FMOD_RESULT result;
result = system->update();
errorCheck(result);
}
}

[/code:2v7zl7oj]

I’m using FMOD_INIT_WASAPI_EXCLUSIVE because it enables low latency according to documentation. I’m using Windows 7 (32bit) and not Vista as specified in the docu, but it leads to the same results as FMOD_INIT_NORMAL.

Could you explain how exactly I’d have to use getRecordPosition?

  • You must to post comments
0
0

Problem solved!! I changed the sample rate from 48000 to 44100 and I removed the Sleep command before system->playSound .

  • You must to post comments
Showing 9 results
Your Answer

Please first to submit.