MainWindow
::MainWindow(QWidget *parent
) : ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&audio_decoder, &QAudioDecoder::bufferReady, this, &MainWindow::on_audio_decoded);
connect(&audio_decoder, static_cast<void(QAudioDecoder::*)(QAudioDecoder::Error)>(&QAudioDecoder::error),
this, &MainWindow::on_audio_decode_error);
connect(&audio_decoder, &QAudioDecoder::stateChanged, this, &MainWindow::on_audio_decoder_stateChanged);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionLoad_Sound_File_triggered()
{
if (!fileName.isEmpty())
{
if (QFile(fileName
).
exists()) {
samples.clear();
audio_decoder.setSourceFilename(fileName);
audio_decoder.start();
}
}
}
void MainWindow::on_audio_decoded()
{
while (audio_decoder.bufferAvailable())
{
QAudioBuffer audio_buffer = audio_decoder.read();
QAudioFormat audio_format = audio_buffer.format();
if (samples.empty())
{
for(int chan_idx = 0; chan_idx < audio_format.channelCount(); ++ chan_idx)
{
samples.push_back(QVector<qreal>());
}
}
switch(audio_format.sampleType())
{
case QAudioFormat::SignedInt:
switch(audio_format.sampleSize())
{
case 8:
NormalizeIntSamples<qint8>
(audio_buffer.
frameCount(), audio_format.
channelCount(), audio_buffer.
constData<qint8>
(),
(QSysInfo::Endian)(audio_format.
byteOrder()), samples
);
break;
case 16:
NormalizeIntSamples<qint16>
(audio_buffer.
frameCount(), audio_format.
channelCount(), audio_buffer.
constData<qint16>
(),
(QSysInfo::Endian)(audio_format.
byteOrder()), samples
);
break;
case 32:
NormalizeIntSamples<qint32>
(audio_buffer.
frameCount(), audio_format.
channelCount(), audio_buffer.
constData<qint32>
(),
(QSysInfo::Endian)(audio_format.
byteOrder()), samples
);
break;
}
break;
case QAudioFormat::UnSignedInt:
switch(audio_format.sampleSize())
{
case 8:
NormalizeIntSamples<quint8>
(audio_buffer.
frameCount(), audio_format.
channelCount(), audio_buffer.
constData<quint8>
(),
(QSysInfo::Endian)(audio_format.
byteOrder()), samples
);
break;
case 16:
NormalizeIntSamples<quint16>
(audio_buffer.
frameCount(), audio_format.
channelCount(), audio_buffer.
constData<quint16>
(),
(QSysInfo::Endian)(audio_format.
byteOrder()), samples
);
break;
case 32:
NormalizeIntSamples<quint32>
(audio_buffer.
frameCount(), audio_format.
channelCount(), audio_buffer.
constData<quint32>
(),
(QSysInfo::Endian)(audio_format.
byteOrder()), samples
);
break;
}
break;
case QAudioFormat::Float:
switch(audio_format.sampleSize())
{
case 64:
NormalizeFloatSamples<double>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<double>(), samples);
break;
case 32:
NormalizeFloatSamples<float>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<float>(), samples);
break;
}
break;
case QAudioFormat::Unknown:
break;
}
}
}
void MainWindow::on_audio_decode_error(QAudioDecoder::Error error)
{
QString decode_error
= audio_decoder.
errorString();
QMessageBox::warning(this,
"Audio Decode Error", decode_error
);
}
void MainWindow::DrawSoundLines()
{
qDebug() << "Drawing.";
pen.setWidth(0);
for(int sample_idx = 1; sample_idx < samples[0].size(); ++sample_idx)
{
QLineF line
(sample_idx, samples
[0][sample_idx
], sample_idx
-1, samples
[0][sample_idx
- 1]);
gs->addLine(line, pen);
}
std::stringstream msg;
msg << "Drew " << samples[0].size() << " samples";
QMessageBox::information(this,
"Audio Decoded", msg.
str().
c_str());
ui->graphicsView->setScene(gs);
}
void MainWindow::on_audio_decoder_stateChanged(QAudioDecoder::State state)
{
if (state == QAudioDecoder::StoppedState)
{
//std::async(&MainWindow::DrawSoundLines,this);
DrawSoundLines();
}
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&audio_decoder, &QAudioDecoder::bufferReady, this, &MainWindow::on_audio_decoded);
connect(&audio_decoder, static_cast<void(QAudioDecoder::*)(QAudioDecoder::Error)>(&QAudioDecoder::error),
this, &MainWindow::on_audio_decode_error);
connect(&audio_decoder, &QAudioDecoder::stateChanged, this, &MainWindow::on_audio_decoder_stateChanged);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionLoad_Sound_File_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this, "Open a sound file", QString(), "Sound Files (*.mp3 *.wav *.ogg)");
if (!fileName.isEmpty())
{
if (QFile(fileName).exists())
{
samples.clear();
audio_decoder.setSourceFilename(fileName);
audio_decoder.start();
}
}
}
void MainWindow::on_audio_decoded()
{
while (audio_decoder.bufferAvailable())
{
QAudioBuffer audio_buffer = audio_decoder.read();
QAudioFormat audio_format = audio_buffer.format();
if (samples.empty())
{
for(int chan_idx = 0; chan_idx < audio_format.channelCount(); ++ chan_idx)
{
samples.push_back(QVector<qreal>());
}
gs = new QGraphicsScene();
}
switch(audio_format.sampleType())
{
case QAudioFormat::SignedInt:
switch(audio_format.sampleSize())
{
case 8:
NormalizeIntSamples<qint8>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<qint8>(), (QSysInfo::Endian)(audio_format.byteOrder()), samples);
break;
case 16:
NormalizeIntSamples<qint16>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<qint16>(), (QSysInfo::Endian)(audio_format.byteOrder()), samples);
break;
case 32:
NormalizeIntSamples<qint32>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<qint32>(), (QSysInfo::Endian)(audio_format.byteOrder()), samples);
break;
}
break;
case QAudioFormat::UnSignedInt:
switch(audio_format.sampleSize())
{
case 8:
NormalizeIntSamples<quint8>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<quint8>(), (QSysInfo::Endian)(audio_format.byteOrder()), samples);
break;
case 16:
NormalizeIntSamples<quint16>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<quint16>(), (QSysInfo::Endian)(audio_format.byteOrder()), samples);
break;
case 32:
NormalizeIntSamples<quint32>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<quint32>(), (QSysInfo::Endian)(audio_format.byteOrder()), samples);
break;
}
break;
case QAudioFormat::Float:
switch(audio_format.sampleSize())
{
case 64:
NormalizeFloatSamples<double>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<double>(), samples);
break;
case 32:
NormalizeFloatSamples<float>(audio_buffer.frameCount(), audio_format.channelCount(), audio_buffer.constData<float>(), samples);
break;
}
break;
case QAudioFormat::Unknown:
break;
}
}
}
void MainWindow::on_audio_decode_error(QAudioDecoder::Error error)
{
QString decode_error = audio_decoder.errorString();
QMessageBox::warning(this, "Audio Decode Error", decode_error);
}
void MainWindow::DrawSoundLines()
{
qDebug() << "Drawing.";
QPen pen;
pen.setWidth(0);
for(int sample_idx = 1; sample_idx < samples[0].size(); ++sample_idx)
{
QLineF line(sample_idx, samples[0][sample_idx], sample_idx -1, samples[0][sample_idx - 1]);
gs->addLine(line, pen);
}
std::stringstream msg;
msg << "Drew " << samples[0].size() << " samples";
QMessageBox::information(this, "Audio Decoded", msg.str().c_str());
ui->graphicsView->setScene(gs);
}
void MainWindow::on_audio_decoder_stateChanged(QAudioDecoder::State state)
{
if (state == QAudioDecoder::StoppedState)
{
//std::async(&MainWindow::DrawSoundLines,this);
DrawSoundLines();
}
}
To copy to clipboard, switch view to plain text mode
{
Q_OBJECT
public:
explicit MainWindow
(QWidget *parent
= 0);
~MainWindow();
private slots:
void on_actionLoad_Sound_File_triggered();
void on_audio_decoded();
void on_audio_decode_error(QAudioDecoder::Error error);
void on_audio_decoder_stateChanged(QAudioDecoder::State state);
private:
Ui::MainWindow *ui;
template<typename T>
void NormalizeIntSamples
(const int frame_count,
const int channel_count,
const T
* sample_data,
QSysInfo::Endian sample_byte_order, QVector<QVector<qreal> >
& samples
) {
for(int frame_idx = 0; frame_idx < frame_count; ++frame_idx)
{
for (int channel_idx = 0; channel_idx < channel_count; ++channel_idx)
{
T sample = 0;
switch (sample_byte_order)
{
sample = qFromBigEndian<T>(sample_data[frame_idx*channel_count + channel_idx]);
sample = qFromLittleEndian<T>(sample_data[frame_idx*channel_count + channel_idx]);
}
samples[channel_idx].push_back((qreal)sample);
}
}
}
template<typename T> void NormalizeFloatSamples(const int frame_count, const int channel_count, const T* sample_data, QVector<QVector<qreal> >& samples)
{
for(int frame_idx = 0; frame_idx < frame_count; ++frame_idx)
{
for (int channel_idx = 0; channel_idx < channel_count; ++channel_idx)
{
samples[channel_idx].push_back((qreal)(sample_data[frame_idx*channel_count + channel_idx]));
}
}
}
void DrawSoundLines();
QAudioDecoder audio_decoder;
QVector<QVector<qreal> > samples;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_actionLoad_Sound_File_triggered();
void on_audio_decoded();
void on_audio_decode_error(QAudioDecoder::Error error);
void on_audio_decoder_stateChanged(QAudioDecoder::State state);
private:
Ui::MainWindow *ui;
template<typename T> void NormalizeIntSamples(const int frame_count, const int channel_count, const T* sample_data, QSysInfo::Endian sample_byte_order, QVector<QVector<qreal> >& samples)
{
for(int frame_idx = 0; frame_idx < frame_count; ++frame_idx)
{
for (int channel_idx = 0; channel_idx < channel_count; ++channel_idx)
{
T sample = 0;
switch (sample_byte_order)
{
case QSysInfo::BigEndian:
sample = qFromBigEndian<T>(sample_data[frame_idx*channel_count + channel_idx]);
case QSysInfo::LittleEndian:
sample = qFromLittleEndian<T>(sample_data[frame_idx*channel_count + channel_idx]);
}
samples[channel_idx].push_back((qreal)sample);
}
}
}
template<typename T> void NormalizeFloatSamples(const int frame_count, const int channel_count, const T* sample_data, QVector<QVector<qreal> >& samples)
{
for(int frame_idx = 0; frame_idx < frame_count; ++frame_idx)
{
for (int channel_idx = 0; channel_idx < channel_count; ++channel_idx)
{
samples[channel_idx].push_back((qreal)(sample_data[frame_idx*channel_count + channel_idx]));
}
}
}
void DrawSoundLines();
QAudioDecoder audio_decoder;
QVector<QVector<qreal> > samples;
QGraphicsScene *gs;
};
To copy to clipboard, switch view to plain text mode
Bookmarks