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

Author Topic: Change Sprite While detect audio  (Read 3805 times)

0 Members and 1 Guest are viewing this topic.

cwmh

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • Email
Change Sprite While detect audio
« on: December 09, 2018, 07:34:42 am »
How to changesprite while detect audio from music

Music sg;
sg.loadFromFile("asd.ogg");

sg.play();

if(sg.getVolume>100){
//sprite changes
}
else{
//sprite fall back
}

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Change Sprite While detect audio
« Reply #1 on: December 09, 2018, 11:14:16 am »
So what's your goal exactly and what do you mean with "detect"?

The volume of the music is set for the whole playback. Volume != amplitude
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

cwmh

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • Email
Re: Change Sprite While detect audio
« Reply #2 on: December 23, 2018, 07:11:27 pm »
Yes, like steins gate game, the texture change while the audios large

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Change Sprite While detect audio
« Reply #3 on: December 30, 2018, 12:35:24 pm »
You need to convert the audio into volume data rather than amplitude/waveform data. That is you need to know how loud you sound is at a particular point in time? You "sample" a few samples around the time (either some before and some after or all before, especially if 'live'/streamed) and calculate its volume. Volume here means perceived volume or loudness, not the overall sound's volume control (sound.setVolume - not this).

A simple way to do this is to simply average the height of the wave over a block of time:
(semi-pseudo code):
auto total{ 0 };
auto currentSampleIndex{ getSampleIndexForCurrentTime };
for (auto i{ 0 }; i < blockSize; ++i)
{
    total += std::abs(sample[currentSampleIndex - i]);
}
total /= blockSize;
total /= 32768;

This should give you something in the range of 0 - 1 that represents its overall volume based on its block size. Note that the maximum volume should practically be around 0.5 unless extremely high or extremely low frequency at extremely high volumes or high DC offsets. The block size you will have to determine yourself but you can try 100, 200, 1000, 10000 or something but be aware that the larger the block, the more work it has to do.
A block size of 10000 on a sample with a sample rate of 44.1Khz is less than a quarter of a second of sound so this may be an acceptable size.


For more accurate results, you could convert to sound units or convert the sound to frequencies and add extra "weight" to the lower frequencies.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*