1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-04 10:19:27 +02:00

ogg passthrough

rename
This commit is contained in:
Philippe G 2021-01-06 22:42:38 -08:00
parent f483075b2c
commit 34bc286d9b
20 changed files with 404 additions and 98 deletions

View file

@ -1,4 +1,5 @@
use super::{Open, Sink};
use crate::audio::AudioPacket;
use alsa::device_name::HintIter;
use alsa::pcm::{Access, Format, Frames, HwParams, PCM};
use alsa::{Direction, Error, ValueOr};
@ -124,8 +125,9 @@ impl Sink for AlsaSink {
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
let mut processed_data = 0;
let data = packet.samples();
while processed_data < data.len() {
let data_to_buffer = min(
self.buffer.capacity() - self.buffer.len(),

View file

@ -1,4 +1,5 @@
use super::{Open, Sink};
use crate::audio::AudioPacket;
use gst::prelude::*;
use gst::*;
use std::sync::mpsc::{sync_channel, SyncSender};
@ -104,9 +105,9 @@ impl Sink for GstreamerSink {
fn stop(&mut self) -> io::Result<()> {
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
// Copy expensively (in to_vec()) to avoid thread synchronization
let deighta: &[u8] = data.as_bytes();
let deighta: &[u8] = packet.samples().as_bytes();
self.tx
.send(deighta.to_vec())
.expect("tx send failed in write function");

View file

@ -1,4 +1,5 @@
use super::{Open, Sink};
use crate::audio::AudioPacket;
use jack::{
AsyncClient, AudioOut, Client, ClientOptions, Control, Port, ProcessHandler, ProcessScope,
};
@ -73,8 +74,8 @@ impl Sink for JackSink {
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
for s in data.iter() {
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
for s in packet.samples().iter() {
let res = self.send.send(*s);
if res.is_err() {
error!("jackaudio: cannot write to channel");

View file

@ -1,3 +1,4 @@
use crate::audio::AudioPacket;
use std::io;
pub trait Open {
@ -7,7 +8,7 @@ pub trait Open {
pub trait Sink {
fn start(&mut self) -> io::Result<()>;
fn stop(&mut self) -> io::Result<()>;
fn write(&mut self, data: &[i16]) -> io::Result<()>;
fn write(&mut self, packet: &AudioPacket) -> io::Result<()>;
}
fn mk_sink<S: Sink + Open + 'static>(device: Option<String>) -> Box<dyn Sink> {

View file

@ -1,4 +1,5 @@
use super::{Open, Sink};
use crate::audio::AudioPacket;
use std::fs::OpenOptions;
use std::io::{self, Write};
use std::mem;
@ -26,12 +27,15 @@ impl Sink for StdoutSink {
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
let data: &[u8] = unsafe {
slice::from_raw_parts(
data.as_ptr() as *const u8,
data.len() * mem::size_of::<i16>(),
)
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
let data: &[u8] = match packet {
AudioPacket::Samples(data) => unsafe {
slice::from_raw_parts(
data.as_ptr() as *const u8,
data.len() * mem::size_of::<i16>(),
)
},
AudioPacket::OggData(data) => data,
};
self.0.write_all(data)?;

View file

@ -1,4 +1,5 @@
use super::{Open, Sink};
use crate::audio::AudioPacket;
use portaudio_rs;
use portaudio_rs::device::{get_default_output_index, DeviceIndex, DeviceInfo};
use portaudio_rs::stream::*;
@ -95,8 +96,8 @@ impl<'a> Sink for PortAudioSink<'a> {
self.0 = None;
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
match self.0.as_mut().unwrap().write(data) {
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
match self.0.as_mut().unwrap().write(packet.samples()) {
Ok(_) => (),
Err(portaudio_rs::PaError::OutputUnderflowed) => error!("PortAudio write underflow"),
Err(e) => panic!("PA Error {}", e),

View file

@ -1,4 +1,5 @@
use super::{Open, Sink};
use crate::audio::AudioPacket;
use libpulse_binding::{self as pulse, stream::Direction};
use libpulse_simple_binding::Simple;
use std::io;
@ -65,13 +66,17 @@ impl Sink for PulseAudioSink {
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
if let Some(s) = &self.s {
// SAFETY: An i16 consists of two bytes, so that the given slice can be interpreted
// as a byte array of double length. Each byte pointer is validly aligned, and so
// is the newly created slice.
let d: &[u8] =
unsafe { std::slice::from_raw_parts(data.as_ptr() as *const u8, data.len() * 2) };
let d: &[u8] = unsafe {
std::slice::from_raw_parts(
packet.samples().as_ptr() as *const u8,
packet.samples().len() * 2,
)
};
match s.write(d) {
Ok(_) => Ok(()),

View file

@ -1,6 +1,7 @@
use super::{Open, Sink};
extern crate cpal;
extern crate rodio;
use crate::audio::AudioPacket;
use cpal::traits::{DeviceTrait, HostTrait};
use std::process::exit;
use std::{io, thread, time};
@ -164,8 +165,8 @@ impl Sink for RodioSink {
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
let source = rodio::buffer::SamplesBuffer::new(2, 44100, data);
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
let source = rodio::buffer::SamplesBuffer::new(2, 44100, packet.samples());
self.rodio_sink.append(source);
// Chunk sizes seem to be about 256 to 3000 ish items long.

View file

@ -1,4 +1,5 @@
use super::{Open, Sink};
use crate::audio::AudioPacket;
use sdl2::audio::{AudioQueue, AudioSpecDesired};
use std::{io, thread, time};
@ -45,12 +46,12 @@ impl Sink for SdlSink {
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
while self.queue.size() > (2 * 2 * 44_100) {
// sleep and wait for sdl thread to drain the queue a bit
thread::sleep(time::Duration::from_millis(10));
}
self.queue.queue(data);
self.queue.queue(packet.samples());
Ok(())
}
}

View file

@ -1,4 +1,5 @@
use super::{Open, Sink};
use crate::audio::AudioPacket;
use shell_words::split;
use std::io::{self, Write};
use std::mem;
@ -43,11 +44,11 @@ impl Sink for SubprocessSink {
Ok(())
}
fn write(&mut self, data: &[i16]) -> io::Result<()> {
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
let data: &[u8] = unsafe {
slice::from_raw_parts(
data.as_ptr() as *const u8,
data.len() * mem::size_of::<i16>(),
packet.samples().as_ptr() as *const u8,
packet.samples().len() * mem::size_of::<i16>(),
)
};
if let Some(child) = &mut self.child {