Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Strange behaviour with onProcessSamples  (Read 3571 times)

0 Members and 1 Guest are viewing this topic.

Voice

  • Newbie
  • *
  • Posts: 3
    • View Profile
Strange behaviour with onProcessSamples
« on: May 03, 2018, 10:53:52 pm »
To start, I am using SFML 2.4.2 and GCC 4.9.2 TDM (SJLJ) - 32-bit on Windows 10.

I have been trying to use SFML to process audio samples from my microphone close to real-time and I have been getting incorrect samples and number of samples going to the onProcessSamples function in my recorder class inherited from sf::SoundRecorder (https://www.sfml-dev.org/tutorials/2.4/audio-recording.php).

In my main file I create a window with a button that, when clicked, starts the recorder with the following code:
    SpeechRecorder micInput;
    if(SpeechRecorder::isAvailable())
    {
        std::cout << "Audio capture available." << std::endl;
        //Start listener
        unsigned int sampleRate = 44100;
        micInput.start(sampleRate);
    }
 

In my files for the custom sound recorder I have the class declaration in the .h file:
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <iostream>
#include <math.h>

using namespace std;
using namespace sf;

class SpeechRecorder : public SoundRecorder
{
public:
    bool onStart() override;
    bool onProcessSamples(const Int16* samples, size_t sampleCount) override;
    void onStop() override;
};
 


Then in my .cpp file I defined the onStart function to set the processing interval to 10 milliseconds:
bool SpeechRecorder::onStart()
{
    // Initialize whatever has to be done before the capture starts
    setProcessingInterval(sf::milliseconds(10));

    // Return true to start playing
    return true;
}
 

Also in the .cpp, onProcessSamples is where I want to be doing the analysis of the audio but this is where I noticed that the values are not what I expected. With a sampling rate of 44100 I believe that each frame of samples should have 441 samples but instead, I get 1378 while the samples themselves are only in the range of about +/-5 when I try talking into the microphone.
bool SpeechRecorder::onProcessSamples(const Int16* samples, size_t sampleCount)
{
    // Do something with the new chunk of samples (store them, send them, ...)
    std::cout << "Sample count: " << sampleCount << std::endl;

    int maxSample = 0;
    for(int i(0); i < sampleCount; i++)
    {
        if (abs(samples[i]) > maxSample)
            maxSample = abs(samples[i]);
    }
    std::cout << "Max sample: " << maxSample << std::endl;
 

    // Return true to continue playing
    return true;
}
 

Is there something preventing onProcessSamples being called every 10 milliseconds and can it be worked around? More importantly, I would appreciate help troubleshooting getting the correct samples from the microphone. I noticed on this topic (https://en.sfml-dev.org/forums/index.php?topic=23725.0) someone reported a similar range of +/-4. Testing getSamples on a SoundBuffer loaded from a wave file I was able to get correct amplitudes but I am at a loss for why the samples being passed into onProcessSamples are not in the full range of Int16. Would it mean my microphone is not picking up any sound?

I am still kind of new to the site so let me know if I need to supply more information or improve my formatting.


Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Strange behaviour with onProcessSamples
« Reply #1 on: May 04, 2018, 06:39:11 am »
Quote
Is there something preventing onProcessSamples being called every 10 milliseconds and can it be worked around?
Don't forget that it is just a hint. Internally, the recorder sends the recording thread to sleep and the actual duration really depends on the OS.

Quote
Would it mean my microphone is not picking up any sound?
Yes, most likely. Make sure that it works outside your app, and that the configured volume for the microphone is high enough.
Laurent Gomila - SFML developer

Voice

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Strange behaviour with onProcessSamples
« Reply #2 on: May 04, 2018, 09:43:02 pm »
I managed to figure out why I wasn't getting the samples I was expecting. I made the silly mistake of just assuming my default recording device was set to my laptops built-in microphone but turns out it wasn't. Setting the correct device appears to give the expected amplitudes.

For the other issue, is it possible to give the recording thread more priority so that the OS doesn't put it to sleep for so long? The start function is directly calling the onStart function so I believe they are called in the main thread, but onProcessSamples and onStop are called in the recording thread. Ideally, I would like my program to have consistent behaviour across platforms so I have been reading through the Threads tutorial (https://www.sfml-dev.org/tutorials/2.4/system-thread.php) to see if I can have more control over the recording thread but I cannot figure out where to start. Will I need to use another library specifically for dealing with threads? Any help would be appreciated.

Voice

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Strange behaviour with onProcessSamples
« Reply #3 on: May 10, 2018, 03:57:29 am »
After installing the newly released SFML 2.5.0 along with a compatible compiler version (GCC 5.1.0 TDM (SJLJ) - Code::Blocks - 32-bit), I am now getting consistent buffer sizes of 441 samples every 10 milliseconds when using a sampleRate of 44100. With my custom recorder now working as intended I'll consider this issue solved.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Strange behaviour with onProcessSamples
« Reply #4 on: May 10, 2018, 12:04:13 pm »
I don't remember what we changed there, but I'm glad it magically solved your problem ;D
Laurent Gomila - SFML developer

 

anything