1
Audio / Minor problem in the tutorial and a question
« on: April 17, 2010, 09:34:23 am »
I finished the program, below you have the source code (maybe someone will find it useful).
There are two minor problems with it:
1)there is a small delay during the playback
2)if you change the Sleep numbers the program will not report accurate values for the Volume and Frequency.
Laurent I found the tutorials and you're hint very helpful: Thank You
I used Visual C++ 2008 and it works (i tested it many times).
There are two minor problems with it:
1)there is a small delay during the playback
2)if you change the Sleep numbers the program will not report accurate values for the Volume and Frequency.
Laurent I found the tutorials and you're hint very helpful: Thank You
I used Visual C++ 2008 and it works (i tested it many times).
Code: [Select]
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio.hpp>
#include <iomanip>
#include <cmath>
#include <iostream>
////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
class MyCustomSoundRecorder : public sf::SoundRecorder
{
virtual bool OnStart()
{
return true;
}
virtual bool OnProcessSamples(const sf::Int16* Samples, std::size_t SamplesCount)
{
sf::SoundBuffer Buffer;
Buffer.LoadFromSamples(Samples,SamplesCount,1,44100); //used for microphone
// playing sound files - if you want to use this feature you must disable the entire
// Recorder class and also all the Recorder references in main()
// You will only leave the inside of the OnProcessSamples() function
// Buffer.LoadFromFile("pana2.wav");
// const sf::Int16* Samples = Buffer.GetSamples();
//------->sStarting to play the Sound
sf::Sound Sound;
Sound.SetBuffer(Buffer);
Sound.Play();
sf::Sleep(0.1f); //small delay so that the Offset will be bigger than 0
//------->Variables for Volume and Frequency Calculation
int i,k,j=0,p=0;
float Volume=0.0,frecventa=0.0;
// Loop while the sound is playing
while (Sound.GetStatus() == sf::Sound::Playing)
{
//Sound.Pause();//Improves accuracy when playing files/does not work with the Recorder class
//------->Volume - The value range is between 0 and 32768(it almost never reaches 32000)
Volume=0.0; // For a x value on a scale 1 to 100 apply the formula x = (int)((100*Volume)/32768);
k=(int)(Sound.GetPlayingOffset()*Buffer.GetSampleRate());//current sample
for(i=j;i<k;i++)
Volume += Samples[i]*Samples[i];
Volume=sqrt(Volume/(k-j));//Value under 5 db are electrical noise(mute the mic if you want to see proof :D)
//j=k;
//-------> Frequency
if (Samples[j]<0.0) p=0; else p=1;//0 - the first sample has a negative amplitude
//1 - the first sample has a pozitive amplitude
frecventa=0.0;//initializing the frequency
for(i=j;i<k;i++)
{ //if a sign change occurs between two samples the frequency number increases
//p variable remembers the sign of the Sample[i-1] (pozitive or negaative)
if ((Samples[i]>0.0)&&(p==0)&&(Samples[i]>20.0)) {//20 is the value of trigger (so that no audio noise is taken in to account)
frecventa++;
p=1;
}
else
if ((Samples[i]<0.0)&&(p==1)&&(Samples[i]<-20.0)) {
frecventa++;
p=0;
};
}
j=k;//este de la volum;ptr ca sa imi usurez viata
//Sound.Play();//Improves accuracy when playing files/does not work with the Recorder class
// Leave some CPU time for other processes
sf::Sleep(0.5f);
//Display Values Volume Time Frequency
std::cout << "\rV T F " << std::fixed << std::setprecision(2) << Volume << " db "<<Sound.GetPlayingOffset() << " sec "<<frecventa <<" Hz "<<std::endl;
}
return true;
}
virtual void OnStop()
{
}
};
// Check that the device can capture audio
if (sf::SoundRecorder::CanCapture() == false)
{
std::cout << "Sorry, audio capture is not supported by your system" << std::endl;
return EXIT_SUCCESS;
}
MyCustomSoundRecorder Recorder;
Recorder.Start(44100);
std::cout << "Recording... press enter to stop";
std::cin.ignore(10000, '\n');
Recorder.Stop();
// Wait until the user presses 'enter' key
std::cout << "Press enter to exit..." << std::endl;
std::cin.ignore(10000, '\n');
return EXIT_SUCCESS;
}