Skip to content

Commit

Permalink
simplify backend audio processing
Browse files Browse the repository at this point in the history
  • Loading branch information
Artemis21 committed Mar 7, 2024
1 parent 47f3613 commit cdf1bac
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/deezer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub async fn track_search(q: &str) -> Result<Vec<Track>> {
Ok(data.data)
}

/// Fetch a track by ID, returning None if we could not deserialise the response (eg. not found).
/// Fetch a track by ID, returning None if it was not found.
pub async fn track(id: Id) -> Result<Option<Track>> {
let url = format!("{API_URL}/track/{id}");
CLIENT
Expand Down
53 changes: 20 additions & 33 deletions src/track/music.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! A cache system for storing preview MP3s from Deezer, and retrieving clips from them.
use std::{ops::Range, sync::OnceLock};

use eyre::{Context, OptionExt, Result};
use eyre::{Context, Result};
use rocket::tokio::{fs, task};

use crate::deezer;
Expand Down Expand Up @@ -51,20 +51,19 @@ fn blocking_save_track(path: std::path::PathBuf, mp3_data: &[u8]) -> Result<()>
let mut writer = hound::WavWriter::new(std::io::BufWriter::new(file), wav_spec)
.wrap_err("error creating a WAV writer")?;
let mut maybe_frame = Ok(first_frame);
while let Ok(frame) = maybe_frame {
loop {
let frame = match maybe_frame {
Ok(frame) => frame,
Err(minimp3::Error::Eof) => return writer.finalize().map_err(Into::into),
Err(err) => return Err(err.into()),
};
for sample in frame.data {
writer
.write_sample(sample)
.wrap_err("error writing a sample to a WAV file")?;
}
maybe_frame = decoder.next_frame();
}
match maybe_frame.expect_err("we looped until it was an error") {
minimp3::Error::Eof => (),
err => Err(err).wrap_err("error decoding an MP3")?,
}
writer.finalize()?;
Ok(())
}

/// Download a track from Deezer and save it to the music cache.
Expand Down Expand Up @@ -103,34 +102,25 @@ fn blocking_clip_track(path: std::path::PathBuf, time: Range<chrono::Duration>)
let mut buf = Vec::new();
let cursor = std::io::Cursor::new(&mut buf);
let mut writer = hound::WavWriter::new(cursor, spec).wrap_err("error creating a WAV writer")?;
let samples_to_read = spec.sample_rate * length / 1000;
assert_eq!(spec.channels, 2, "Deezer should return stereo music");
let sample_rate = usize::try_from(spec.sample_rate).expect("sample rate should fit in usize");
let samples_to_read = usize::from(spec.channels)
* sample_rate
* usize::try_from(length).expect("length in ms should fit in usize")
/ 1000;
let mut samples_read = 0;
for _ in 0..samples_to_read {
let Some(left) = reader
.samples::<i16>()
.next()
.transpose()
.wrap_err("could not read sample from track")?
else {
break;
};
let right = reader
.samples::<i16>()
.next()
.ok_or_eyre("expected a right sample after a left sample")?
.wrap_err("could not read sample from track")?;
for sample in reader.samples::<i16>().take(samples_to_read) {
let sample = sample.wrap_err("could not read sample from track")?;
writer
.write_sample(left)
.wrap_err("error writing a (left) sample to a WAV file")?;
writer
.write_sample(right)
.wrap_err("error writing a (right) sample to a WAV file")?;
.write_sample(sample)
.wrap_err("error writing a sample to a WAV file")?;
samples_read += 1;
}
// the length of the preview should be 30 seconds, but sometimes it's a little under
let remaining_samples = samples_to_read - samples_read;
if remaining_samples > spec.sample_rate / 2 {
if remaining_samples > sample_rate {
// if it's more than half a second under, error
// (`remaining_samples` is doubled because we're counting individual values from stereo music)
Err(eyre::eyre!(
"could not read enough samples from track ({} < {})",
samples_read,
Expand All @@ -141,10 +131,7 @@ fn blocking_clip_track(path: std::path::PathBuf, time: Range<chrono::Duration>)
for _ in 0..remaining_samples {
writer
.write_sample(0)
.wrap_err("error writing (left) padding to a WAV file")?;
writer
.write_sample(0)
.wrap_err("error writing (right) padding to a WAV file")?;
.wrap_err("error writing padding to a WAV file")?;
}
}
writer.finalize()?;
Expand Down

0 comments on commit cdf1bac

Please sign in to comment.