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

Author Topic: How do I seamlessly loop recorded sounds?  (Read 7552 times)

0 Members and 1 Guest are viewing this topic.

Joshua Flynn

  • Full Member
  • ***
  • Posts: 133
    • View Profile
How do I seamlessly loop recorded sounds?
« on: August 29, 2012, 09:16:43 pm »
I've built a class on sf::SoundBufferRecorder, and it automates the recording, buffering and sound creation process. I want to then be able to play the sounds that it records in a seamless loop. .SetLoop(true) does not give seamless looping. How would I go about doing this?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: How do I seamlessly loop recorded sounds?
« Reply #1 on: August 29, 2012, 09:29:43 pm »
Quote
SetLoop(true) does not give seamless looping
And you think it's SFML's fault? As far as I know, looping sounds loop perfectly (there's no lag between the end and the beginning). Couldn't it be something on your side? Does it work with a loaded sound rather than a recorded one?
Laurent Gomila - SFML developer

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
Re: How do I seamlessly loop recorded sounds?
« Reply #2 on: August 29, 2012, 09:34:28 pm »
If by "seamless" you mean that silence at the beginning and the end of the sound should be trimmed away, that might be harder than it appears.

Generally, go at it like you were to trim a text string when you want to remove all leading and trailing whitespace: get the sample data of the recorded sample and "browse" through it until you find an actual sound sample (ie anything that is not silence) and save that position. Do the same in reverse, beginning at the end of the recorded sound. Use the positions that you saved to get a sub-sound of the recorded sound, that would be the trimmed sound that you could repeat "seamlessly".

The problem is that there is likely not going to be any true silence in the recorded sample but a certain amount of noise (especially when recording using a microphone). You will have to define a reasonable treshold where any sample that is quieter than the treshold will be considered absolute silence. It should not be too high, because that would trim away actual sound data, and it should not be too low either because then it won't fix the problem.

It also cannot be a fix value, because user A might speak louder than user B and the correct treshold would thus be different - so you'd have to do some pre-analysis of the sample as well (could be done while recording).
JSFML - The Java binding to SFML.

Joshua Flynn

  • Full Member
  • ***
  • Posts: 133
    • View Profile
Re: How do I seamlessly loop recorded sounds?
« Reply #3 on: August 29, 2012, 09:45:20 pm »
Quote
SetLoop(true) does not give seamless looping
And you think it's SFML's fault? As far as I know, looping sounds loop perfectly (there's no lag between the end and the beginning). Couldn't it be something on your side? Does it work with a loaded sound rather than a recorded one?

A loaded sound?!

Sorry, what loaded sound?

Records the sound with SoundBufferRecorder, .GetBuffer() stores it in a SoundBuffer (SFML's own), passes that to Sound (SFML's own), sets the Sound with .SetLoop(true), then .Play(). Sound loops, there's a gap.  Why would it be anything on 'my side'? You make it sound like I'm trying to intentionally slur you or something.

 
    sf::SoundBufferRecorder Test;
    Test.Start();
    system("PAUSE");
    Test.Stop();
    sf::SoundBuffer Test2;
    Test2 = Test.GetBuffer();

    sf::Sound Test3;
    Test3.SetBuffer(Test2);

    Test3.SetLoop(true);
    Test3.Play();
    system("PAUSE");
    return 0;
 

Replace system("PAUSE"); with whatever pause preference you have. There's a gap in the loop. Try humming a constant note and you'll notice it.
« Last Edit: August 29, 2012, 09:49:36 pm by Joshua Flynn »

Joshua Flynn

  • Full Member
  • ***
  • Posts: 133
    • View Profile
Re: How do I seamlessly loop recorded sounds?
« Reply #4 on: August 29, 2012, 09:48:13 pm »
If by "seamless" you mean that silence at the beginning and the end of the sound should be trimmed away, that might be harder than it appears.

Generally, go at it like you were to trim a text string when you want to remove all leading and trailing whitespace: get the sample data of the recorded sample and "browse" through it until you find an actual sound sample (ie anything that is not silence) and save that position. Do the same in reverse, beginning at the end of the recorded sound. Use the positions that you saved to get a sub-sound of the recorded sound, that would be the trimmed sound that you could repeat "seamlessly".

The problem is that there is likely not going to be any true silence in the recorded sample but a certain amount of noise (especially when recording using a microphone). You will have to define a reasonable treshold where any sample that is quieter than the treshold will be considered absolute silence. It should not be too high, because that would trim away actual sound data, and it should not be too low either because then it won't fix the problem.

It also cannot be a fix value, because user A might speak louder than user B and the correct treshold would thus be different - so you'd have to do some pre-analysis of the sample as well (could be done while recording).

It's not recorded silence (that would generate static noise) unless it's system appended silence before the recording actually starts (that is entirely silent) - but I wouldn't know how to remove that. There's just a notable silent gap, not even background noise or static.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: How do I seamlessly loop recorded sounds?
« Reply #5 on: August 29, 2012, 10:53:54 pm »
Quote
A loaded sound?!

Sorry, what loaded sound?
I mean you should try with a sound loaded from a file, as opposed to a sound recorded by you. To know whether the problem is with recording or looping.

Quote
Why would it be anything on 'my side'? You make it sound like I'm trying to intentionally slur you or something.
Hum, no. Just trying to investigate. Sorry but we can't know everything about your problem just from a 2-line post, we need to ask questions.
Laurent Gomila - SFML developer

Joshua Flynn

  • Full Member
  • ***
  • Posts: 133
    • View Profile
Re: How do I seamlessly loop recorded sounds?
« Reply #6 on: August 30, 2012, 11:58:49 am »
I mean you should try with a sound loaded from a file, as opposed to a sound recorded by you. To know whether the problem is with recording or looping.

I analysed the recorded audio, and there's a few moments worth (0.5 of a second I think) of 'silence' where there is no recording occurring (as in no noise is being recorded, not even background noise). When the sound loops, the silence makes it sound like there's a gap.

If I remove this gap using an external audio program, the looping is fine.

Assuming the length of the silence is the same, is there a way to 'cut out' the first 0.5 second segment of the sound with SFML? I'm not bothered if cutting it off involves an expensive copying of an array as this isn't entirely concerned with efficiency, but I don't want to export to an external audio program to edit out silence.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: How do I seamlessly loop recorded sounds?
« Reply #7 on: August 30, 2012, 12:17:53 pm »
Thanks, I'll test it myself and see if this silence can be avoided.

You can easily remove audio samples:
sf::SoundBuffer buffer; // loaded with your recorded sound

int begin = buffer.getSampleRate() * buffer.getChannelCount() * 0.5f; // 0.5 seconds
sf::SoundBuffer withoutSilence;
withoutSilence.loadFromSamples(buffer.getSamples() + begin, buffer.getSampleCount() - begin, buffer.getSampleRate(), buffer.getChannelCount());
Laurent Gomila - SFML developer

Joshua Flynn

  • Full Member
  • ***
  • Posts: 133
    • View Profile
Re: How do I seamlessly loop recorded sounds?
« Reply #8 on: August 30, 2012, 12:44:35 pm »
Thanks laurent! As it's a class I'll put it into an automated function.