monolib 0.7.1

A library implementing the lonely radio audio streaming protocol
Documentation
use std::io::{Cursor, Read};

use byteorder::{LittleEndian, ReadBytesExt};
use lonelyradio_types::{Encoder, FragmentMetadata, TrackMetadata};
use symphonia_core::{
	audio::SampleBuffer,
	codecs::{Decoder, CODEC_TYPE_ALAC},
	formats::Packet,
};

pub(crate) fn decode(
	mut stream: impl ReadBytesExt,
	md: &TrackMetadata,
	fmd: &FragmentMetadata,
) -> anyhow::Result<Vec<f32>> {
	let mut samples = vec![];
	match md.encoder {
		Encoder::Pcm16 => {
			let mut samples_i16 = vec![0; fmd.length as usize / 2];
			stream.read_i16_into::<LittleEndian>(&mut samples_i16)?;
			samples
				.append(&mut samples_i16.iter().map(|sample| *sample as f32 / 32767.0).collect());
		}
		Encoder::PcmFloat => {
			let mut samples_f32 = vec![0f32; fmd.length as usize / 4];
			stream.read_f32_into::<LittleEndian>(&mut samples_f32)?;
			samples.append(&mut samples_f32);
		}
		Encoder::Flac => {
			#[cfg(feature = "alac")]
			{
				let take = std::io::Read::by_ref(&mut stream).take(fmd.length);
				let mut reader = claxon::FlacReader::new(take)?;
				samples.append(
					&mut reader
						.samples()
						.map(|x| x.unwrap_or(0) as f32 / 32768.0 / 256.0)
						.collect::<Vec<f32>>(),
				);
			}

			#[cfg(not(feature = "flac"))]
			{
				unimplemented!("flac decoding is disabled in library")
			}
		}
		Encoder::Alac => {
			#[cfg(feature = "alac")]
			{
				let mut buf = vec![];
				std::io::Read::by_ref(&mut stream).take(fmd.length).read_to_end(&mut buf)?;
				let mut reader = symphonia_codec_alac::AlacDecoder::try_new(
					symphonia_core::codecs::CodecParameters::default()
						.for_codec(CODEC_TYPE_ALAC)
						.with_extra_data(fmd.magic_cookie.clone().unwrap().into_boxed_slice()),
					&symphonia_core::codecs::DecoderOptions {
						verify: false,
					},
				)?;
				let decoded = reader.decode(&Packet::new_from_slice(0, 0, 0, &buf))?;
				let mut byte_buf =
					SampleBuffer::<f32>::new(decoded.capacity() as u64, *decoded.spec());
				byte_buf.copy_interleaved_ref(decoded);
				samples.extend(byte_buf.samples());
			}
			#[cfg(not(feature = "alac"))]
			{
				unimplemented!("alac decoding is disabled in library")
			}
		}
		Encoder::Vorbis => {
			#[cfg(feature = "vorbis")]
			{
				let mut buf = vec![];
				std::io::Read::by_ref(&mut stream).take(fmd.length).read_to_end(&mut buf)?;
				let mut decoder = vorbis_rs::VorbisDecoder::new(Cursor::new(buf))?;
				let mut interleaved = vec![];

				while let Some(decoded_block) = decoder.decode_audio_block()? {
					let s = decoded_block.samples();
					interleaved.resize(s[0].len() * s.len(), 0f32);
					for (ind, channel) in s.iter().enumerate() {
						for (samind, sample) in channel.iter().enumerate() {
							interleaved[ind + samind * md.channels as usize] = *sample;
						}
					}
					samples.extend(interleaved);
					interleaved = vec![];
				}
			}
			#[cfg(not(feature = "vorbis"))]
			{
				unimplemented!("vorbis decoding is disabled in library")
			}
		}
		Encoder::Aac | Encoder::Opus | Encoder::WavPack => unimplemented!(),
	};
	Ok(samples)
}