Bonsoir !
Je bosse en ce moment sur un petit logiciel audio qui se base sur la librairie audio de la SFML. J'essaye depuis quelques temps d'implémenter le spectre audio à partir du buffer mais sans succès. Je me suis tourné vers la classe FFT d'audacity mais le problème est que pour faire fonctionner l'algo il faut lui passer le buffer sous forme de float* et je ne vois aucun moyen de récupérer un tel tableau à partir du buffer :/
De plus j'ai quelques doutes quand à la taille du buffer à passer à la fonction dans l'exemple sur lequel je me base cette taille était de 256, c'est acceptable ? (
l'exemple en question)
Voilà ma classe :
#ifndef SOUNDWAVE_H
#define SOUNDWAVE_H
#include <iostream>
#include <memory>
#include "SFML/Audio.hpp"
#include "FFT.h"
#define BUFFER_SIZE 256
#define NUM_WINDOWS 80
class SoundWave
{
public:
SoundWave();
SoundWave(std::shared_ptr<sf::SoundBuffer> buffer); //!< must be the default ctor
virtual ~SoundWave();
void update();
private:
/**
* Initialize the freq array.
* @see SoundWave()
*/
void init();
std::shared_ptr<sf::SoundBuffer> _buffer; //!< audio buffer to work with
FFT _fft;
float magnitude[BUFFER_SIZE]; //!< contain the magntiude data from buffer once _fft.powerSpectrum() method is called
float phase[BUFFER_SIZE]; //!< contain the phase data from buffer once _fft.powerSpectrum() method is called
float power[BUFFER_SIZE]; //!< contain the power data from buffer once _fft.powerSpectrum() method is called
float* freq[NUM_WINDOWS][BUFFER_SIZE/2];
float* freq_phase[NUM_WINDOWS][BUFFER_SIZE/2];
};
#endif // SOUNDWAVE_H
#include "../header/SoundWave.h"
SoundWave::SoundWave()
{
//ctor
}
SoundWave::SoundWave(std::shared_ptr<sf::SoundBuffer> buffer)
{
_buffer = buffer;
init();
}
SoundWave::~SoundWave()
{
//dtor
}
void SoundWave::update()
{
float avg_power = 0.0f;
static int index = 0;
if(index < NUM_WINDOWS)
index += 1;
else
index = 0;
_fft.powerSpectrum(0,BUFFER_SIZE/2,,BUFFER_SIZE,&magnitude[0],&phase[0],&power[0],&avg_power) //!< manque le buffer ici
for (j=1; j<BUFFER_SIZE/2; j++)
{
freq[index][j] = magnitude[j]; //!< fill the array with corresponding data from the magnitude array
}
}
void SoundWave::init()
{
for(int i=0; i < NUM_WINDOWS; i++)
{
for(int j=0; j < NUM_WINDOWS; j++)
{
freq[i][j] = 0;
}
}
}
J'ai également vu pas mal de topic sur le même sujet (
[1],
[2]) et j'ai vu qu'ils utilisaient la structure sf::SoundBuffer::Chunk sauf que je ne vois aps trop comment l'implémenter.
En clair j'aimerai que depuis mon pointeur vers le buffer je puisse jouer la musique et afficher le spectre !
Et pour pas faire deux topics j'ai une secondes question moins importantes :
Pour seek à un certain moment de la musique, y'a un meilleur moyen que celui-là ? :
m_currentSample = static_cast<std::size_t>(timeOffset.asSeconds() * getSampleRate() * getChannelCount());
Le soucis avec cette méthode c'est qu'il y a un décalage de 1 secondes entre l'appel de la méthode et le changement de sample réel, du coup c'est un peu bizarre..
merci d'avance !