audio: rewrote audio cache to write to contiguous segments rather than one long file

Fixes issues with PCM file placement, optimizes some audio-based timeline
and cache operations, just generally a better approach.
This commit is contained in:
itsmattkc
2020-10-11 23:27:40 +11:00
parent 920a15d2ea
commit f7ab0bb640
17 changed files with 575 additions and 226 deletions
+13 -9
View File
@@ -63,11 +63,13 @@ void AudioWaveformView::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
if (!playback_) {
return;
}
const AudioParams& params = playback_->GetParameters();
if (!playback_
|| playback_->GetPCMFilename().isEmpty()
|| !params.is_valid()) {
if (!params.is_valid()) {
return;
}
@@ -78,9 +80,9 @@ void AudioWaveformView::paintEvent(QPaintEvent *event)
cached_waveform_ = QPixmap(size());
cached_waveform_.fill(Qt::transparent);
QFile fs(playback_->GetPCMFilename());
QIODevice* fs = playback_->CreatePlaybackDevice();
if (fs.open(QFile::ReadOnly)) {
if (fs->open(QFile::ReadOnly)) {
QPainter wave_painter(&cached_waveform_);
@@ -89,13 +91,13 @@ void AudioWaveformView::paintEvent(QPaintEvent *event)
int drew = 0;
fs.seek(params.samples_to_bytes(ScreenToUnitRounded(0)));
fs->seek(params.samples_to_bytes(ScreenToUnitRounded(0)));
for (int x=0; x<width() && !fs.atEnd(); x++) {
for (int x=0; x<width() && !fs->atEnd(); x++) {
int samples_len = ScreenToUnitRounded(x+1) - ScreenToUnitRounded(x);
int max_read_size = params.samples_to_bytes(samples_len);
QByteArray read_buffer = fs.read(max_read_size);
QByteArray read_buffer = fs->read(max_read_size);
// Detect whether we've reached EOF and recalculate sample count if so
if (read_buffer.size() < max_read_size) {
@@ -117,9 +119,11 @@ void AudioWaveformView::paintEvent(QPaintEvent *event)
cached_scale_ = GetScale();
cached_scroll_ = GetScroll();
fs.close();
fs->close();
}
delete fs;
}
QPainter p(this);
+13 -14
View File
@@ -204,8 +204,8 @@ void ViewerWidget::ConnectNodeInternal(ViewerOutput *n)
UpdateStack();
waveform_view_->SetViewer(GetConnectedNode()->audio_playback_cache());
if (GetConnectedTimelinePoints()) {
waveform_view_->SetViewer(GetConnectedNode()->audio_playback_cache());
waveform_view_->ConnectTimelinePoints(GetConnectedTimelinePoints());
}
@@ -512,23 +512,24 @@ void ViewerWidget::PushScrubbedAudio()
{
if (!IsPlaying() && Config::Current()["AudioScrubbing"].toBool()) {
// Get audio src device from renderer
QString audio_fn = GetConnectedNode()->audio_playback_cache()->GetPCMFilename();
QFile audio_src(audio_fn);
AudioPlaybackCache::PlaybackDevice* audio_src = GetConnectedNode()->audio_playback_cache()->CreatePlaybackDevice();
if (audio_src.open(QFile::ReadOnly)) {
if (audio_src->open(QIODevice::ReadOnly)) {
const AudioParams& params = GetConnectedNode()->audio_playback_cache()->GetParameters();
// FIXME: Hardcoded scrubbing interval (20ms)
int size_of_sample = params.time_to_bytes(rational(20, 1000));
// Push audio
audio_src.seek(params.time_to_bytes(GetTime()));
QByteArray frame_audio = audio_src.read(size_of_sample);
audio_src->seek(params.time_to_bytes(GetTime()));
QByteArray frame_audio = audio_src->read(size_of_sample);
AudioManager::instance()->SetOutputParams(params);
AudioManager::instance()->PushToOutput(frame_audio);
audio_src.close();
audio_src->close();
}
delete audio_src;
}
}
@@ -628,13 +629,11 @@ void ViewerWidget::FinishPlayPreprocess()
{
int64_t playback_start_time = ruler()->GetTime();
QString audio_fn = GetConnectedNode()->audio_playback_cache()->GetPCMFilename();
if (!audio_fn.isEmpty()) {
AudioManager::instance()->SetOutputParams(GetConnectedNode()->audio_playback_cache()->GetParameters());
AudioManager::instance()->StartOutput(audio_fn,
GetConnectedNode()->audio_playback_cache()->GetParameters().time_to_bytes(GetTime()),
playback_speed_);
}
AudioPlaybackCache* audio_cache = GetConnectedNode()->audio_playback_cache();
AudioManager::instance()->SetOutputParams(audio_cache->GetParameters());
AudioManager::instance()->StartOutput(audio_cache,
audio_cache->GetParameters().time_to_bytes(GetTime()),
playback_speed_);
playback_timer_.Start(playback_start_time, playback_speed_, timebase_dbl());