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

Merge branch 'dev' into tokio_migration

This commit is contained in:
johannesd3 2021-02-23 14:45:01 +01:00 committed by Johannesd3
commit 678d1777fd
32 changed files with 674 additions and 360 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<()>;
}
pub type SinkBuilder = fn(Option<String>) -> Box<dyn Sink + Send>;

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

@ -6,6 +6,7 @@ use cpal::traits::{DeviceTrait, HostTrait};
use thiserror::Error;
use super::{Open, Sink};
use crate::audio::AudioPacket;
#[derive(Debug, Error)]
pub enum RodioError {
@ -178,8 +179,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 {