|
From: Lasse Kärkkäi. <tr...@us...> - 2011-02-04 15:27:58
|
Module: editor
Branch: master
Commit: 7bd4b0fce3ae9630b30add1947d3bf9fe98c2924
Author: Lasse Karkkainen <tro...@tr...>
Date: Fri Feb 4 16:26:13 2011 +0100
Fix issues with analyzing music file
* Would analyze at most processStep samples per audio block (discarding the end of the song)
* Only half of each block was actually output (causing artifacts and discarding half of the audio data)
---
ffmpeg.cc | 4 ++--
ffmpeg.hh | 2 +-
pitch.cc | 2 +-
pitchvis.cc | 35 +++++++++++++++++++----------------
4 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/ffmpeg.cc b/ffmpeg.cc
index 84a14cf..e533b88 100644
--- a/ffmpeg.cc
+++ b/ffmpeg.cc
@@ -167,8 +167,8 @@ void FFmpeg::decodeNextFrame() {
// Move forward within the packet
packetSize -= decodeSize;
packetData += decodeSize;
- // Convert outsize from bytes into number of frames (samples)
- outsize /= sizeof(qint16) * pAudioCodecCtx->channels;
+ // Convert outsize from bytes into number of samples
+ outsize /= sizeof(qint16);
// Calculate new positions
if (packet.time() == packet.time()) m_position = packet.time();
else m_position += outsize / audioQueue.samplesPerSecond();
diff --git a/ffmpeg.hh b/ffmpeg.hh
index c904471..7763b42 100644
--- a/ffmpeg.hh
+++ b/ffmpeg.hh
@@ -61,7 +61,7 @@ public:
void setRateChannels(unsigned rate, unsigned channels) { m_rate = rate; m_channels = channels; }
unsigned getRate() { return m_rate; }
unsigned getChannels() { return m_channels; }
- AudioQueue(unsigned capacity = (2 << 20)): m_ring(capacity), m_channels(), m_position(), m_size(), m_eof() {}
+ AudioQueue(unsigned capacity = 32768): m_ring(capacity), m_channels(), m_position(), m_size(), m_eof() {}
private:
QMutex m_mutex;
diff --git a/pitch.cc b/pitch.cc
index ec54316..e5dab9e 100644
--- a/pitch.cc
+++ b/pitch.cc
@@ -150,7 +150,7 @@ void Analyzer::temporalMerge(Tones& tones) {
}
}
}
- m_moments.push_back(Moment(m_moments.size() * FFT_STEP / m_rate));
+ m_moments.push_back(Moment(m_moments.size() * processStep() / m_rate));
m_moments.back().stealTones(tones); // No pointers are invalidated
}
diff --git a/pitchvis.cc b/pitchvis.cc
index b275144..34611f3 100644
--- a/pitchvis.cc
+++ b/pitchvis.cc
@@ -28,28 +28,31 @@ void PitchVis::run()
position = 0.0;
duration = mpeg.duration(); // Estimation
}
+ unsigned rate = mpeg.audioQueue.getRate();
unsigned channels = mpeg.audioQueue.getChannels();
if (channels == 0) throw std::runtime_error("No audio channels found");
- std::vector<Analyzer> analyzers(channels, Analyzer(mpeg.audioQueue.getRate(), ""));
+ std::vector<Analyzer> analyzers(channels, Analyzer(rate, ""));
// Process the entire song
std::vector<float> data;
+ data.reserve((duration + 1.0) * rate * channels);
unsigned x = 0;
while (mpeg.audioQueue.output(data)) {
- // Read until enough data is available
- if (data.size() / channels - x < analyzers[0].processSize()) continue;
- // Pitch detection
- for (unsigned ch = 0; ch < channels; ++ch) {
- analyzers[ch].process(da::step_iterator<float>(&data[x * channels + ch], channels));
- }
- x += analyzers[0].processStep();
- // Update progress and check for quit flag
- QMutexLocker locker(&mutex);
- if (cancelled) return;
- Analyzer::Moments const& moments = analyzers[0].getMoments();
- if (!moments.empty()) {
- double t = moments.back().time();
- position = t;
- duration = std::max(duration, t + 0.01);
+ // Process as much as can be processed at this point
+ while (data.size() / channels - x >= analyzers[0].processSize()) {
+ // Pitch detection
+ for (unsigned ch = 0; ch < channels; ++ch) {
+ analyzers[ch].process(da::step_iterator<float>(&data[x * channels + ch], channels));
+ }
+ x += analyzers[0].processStep();
+ // Update progress and check for quit flag
+ QMutexLocker locker(&mutex);
+ if (cancelled) return;
+ Analyzer::Moments const& moments = analyzers[0].getMoments();
+ if (!moments.empty()) {
+ double t = moments.back().time();
+ position = t;
+ duration = std::max(duration, t + 0.01);
+ }
}
}
// Filter the analyzer output data into QPainterPaths.
|