Giter Site home page Giter Site logo

alsa-rs's People

Contributors

alexmoon avatar bobo1239 avatar boddlnagg avatar calvinkosmatka avatar carlgreen avatar chadmed avatar chrissie-c avatar damirka avatar danieljrmay avatar derekdreery avatar diwic avatar f35idk avatar flowkclav avatar henquist avatar jake-shadle avatar jasonlg1979 avatar jbeich avatar jkristell avatar joerg-krause avatar lrbalt avatar mbodmer avatar mbyzhang avatar modprog avatar nbonaparte avatar okeri avatar peng1999 avatar rtzoeller avatar wadelma avatar xmac94x avatar xtibor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alsa-rs's Issues

Seq: CC events incorrectly formatted after sending SysEx

When trying to work with external hardware, I have noticed a possible bug in the Seq implementation that caused some me some trouble. Basically what happens is that after sending a piece of SysEx data every CC message becomes malformed, with their status byte zeroed out.

The issue seems to "fix" itself after sending a note event, which is what I currently use as a work around, ending every SysEx message with a note sent to an unused channel.

An easy way to reproduce this is to run the following piece of code and connect it to a raw MIDI endpoint, such as amidi: https://gist.github.com/kelytha/24dfda03ab7eca203d34119a462e429c

The output looks like this on my end:

$ amidi -p virtual -d
90 08 7F  // Note on
   08 00  // Note off
B0 08 7F  // CC up
   08 00  // CC down
F0 00 21 09 15 00 4D 50 00 01 4D 01 F7 // SysEx
F0 00 21 09 15 00 4D 50 00 01 4D 00 F7 // SysEx
08  // ...
7F  // ... garbled CC
08  // ...
00  // ...
90 08 7F  // Note on
   08 00  // Note off
B0 08 7F  // Now CC looks good again!
   08 00

Please yank 0.5.1 and release as 0.6.0

The nix dependency version has been updated in 0.5.1 (c444589), but the nix's types are used in the public API of alsa, so this breaks downstreams such as cpal.

error[E0308]: mismatched types
   --> /home/parallels/.cargo/registry/src/github.com-1ecc6299db9ec823/cpal-0.13.4/src/host/alsa/mod.rs:245:26
    |
244 |         let handle = match handle_result {
    |                            ------------- this expression has type `std::result::Result<host::alsa::alsa::PCM, (host::alsa::alsa::Error, Option<host::alsa::alsa::nix::errno::Errno>)>`
245 |             Err((_, Some(nix::errno::Errno::EBUSY))) => {
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `host::alsa::alsa::nix::errno::Errno`, found enum `nix::errno::Errno`
    |
    = note: perhaps two different versions of crate `nix` are being used?

`nix` dependency is out of date

nix has since updated to 0.26, currently this library is still on 0.24, which is causing duplicated code and slower compilations. Just as in #103 is there any chance of updating this dependency? It looks like it should be backwards compatible in what this library uses from it for a quick look.

No snd_ctl_subscribe_events()?

Can't find it in docs, and searched in the source code. There seems to be no way to subscribe to events with snd_ctl_subscribe_events.
What I want to do is to wait for events, then get volume information. Waiting for events can be done like this in C:

    const char *ctlname = "default";
    snd_ctl_t *ctl;
    assert( snd_ctl_open(&ctl, ctlname, SND_CTL_READONLY) == 0 );
    assert( snd_ctl_subscribe_events(ctl, 1) == 0 );

    struct pollfd* fd = malloc(sizeof(struct pollfd));
    snd_ctl_poll_descriptors(ctl, fd, 1);


    while (1) {
        err = poll(fd, 1, -1);
        while (snd_ctl_read(ctl, event) > 0) {
                 ..... etc .....

Segfault on alpine linux in alsa::pcm::PCM::open

alsa::pcm::PCM::open (pcm.rs:135) due to (as far as i can tell) the variable 'r' being 0x0

I'm not sure how to proceed, the program i've been using to narrow it down was this from the synth-example

fn main() {
    let args: Vec<_> = std::env::args().collect();
    let req_devname = format!("hw:{}", args[1]);
    let p = alsa::PCM::new(&req_devname, alsa::Direction::Playback, false);
 }

Might it be an issue from alpine using musl?

0.2.0 breaks pcm.recover use case

On updating alsa-rs to 0.2.0 I noticed that you changed the way errors are handled now.
While I think the nix package provides a nice way of representing the errno in rust, I unfortunately don't see a nice way how to use pcm.recover(), which needs the original error code as an integer value.

Maybe it's a good idea to add the error code together with the code() method back to the Error struct to be able to use recover, or is there a better way of doing this?
Alternatively I could probably map nix::errno::{EINTR,EPIPE,ESTRPIPE} back to the libc:: values myself.

PCM capture to playback and dropouts

I've been using alsa-rs for a while now, and I have to say that it's my favorite audio streaming & MIDI crate by far. It allows me to do almost everything I once did in C with ALSA, but without the all the super verbose error handling.

I've successfully integrated alsa-rs in my real-time synthesizer engine, and it works like a charm. Superficially, audio capture also works in this engine, but when it starts using more CPU time (>50%), the audio drop outs start. Disable capture and you can push it up to 90%. I'm doing 512 frame latency @ 48 kHz on a PREEMPT kernel, and capturing from the same device as I'm playing on.

What I'm trying to do here is mixing captured audio directly with synthesized sound. I think for this to work you'd need to fill up your playback stream, forward your capture stream, and then start capturing. I'm linking playback and capture via alsa::pcm::link(). The problem is that forwarding is not supported in alsa-rs.. Is there any way around this?

supported snd_pcm_set_params API

Hello, I am using this library for sound card development, but I find that this library lacks the snd_pcm_set_params API interface. Can you support this interface?

Wrap MIDI APIs

If this crate also contained the MIDI APIs, I could use it in https://github.com/Boddlnagg/midir. Since you say that these APIs are not implemented "mostly because nobody asked for them", I'm just going to ask for them now ๐Ÿ˜‰

I'm currently wrapping some parts myself (https://github.com/Boddlnagg/midir/blob/master/src/backend/alsa/wrappers.rs), mostly to be able to use RAII, but I'm not sure if those wrappers are actually safe. They are used in https://github.com/Boddlnagg/midir/blob/master/src/backend/alsa/mod.rs (ALSA is actually the most complicated of the backends in midir ...).

Document MidiEvent::encode

MidiEvent::encode really needs documentation as to what it does.

From the signature and the implementation I can see that it returns (in case of success) the number of bytes consumed from the buffer as well as the encoded event (or None if no complete message was encoded).

Then it also needs to be documented that the event buffer is copied for long (sysex) messages. I guess this is because the documentation of snd_midi_event_encode states that

When this function returns a system exclusive sequencer event (ev->type is SND_SEQ_EVENT_SYSEX), the data pointer (ev->data.ext.ptr) points into the MIDI event parser's buffer. Therefore, the sequencer event can only be used as long as that buffer remains valid, i.e., until the next call to snd_midi_event_encode, snd_midi_event_encode_byte, snd_midi_event_resize_buffer, snd_midi_event_init, snd_midi_event_reset_encode, or snd_midi_event_free for that MIDI event parser.

This makes me wonder whether it might be possible to encode this in the Rust typesystem using lifetimes, instead of requiring a copy?

Furthermore, the documentation of snd_seq_event_input (where currently the data is also copied by Event::extract) has no such comment, which makes me wonder if the buffer there is managed by the event itself (because there is no separate underlying buffer).

Tag off a release?

Hi,

We're looking to release software dependent on this crate, however find ourselves
having to carry a downstream branch frozen at 2fec79bd4cbf. This is obviously
not ideal. Would it be possible to tag off a release so that we can get rid of our
downstream branch and use the crate properly?

Thanks :)

EIO on readi in blocking mode

Thanks for this very nice library! I'm using it in a DSP project and it's working very well.
But now I'm pretty stuck on an issue and need a little help. As far as I understand, when there is no data coming and we are in blocking mode, then readi (https://docs.rs/alsa/0.4.3/alsa/pcm/struct.IO.html#method.readi) should just wait forever or return with one of EBADFD, EPIPE or ESTRPIPE.
My problem is that I get EIO. The specific case I'm struggling with is when capturing from an spdif input on a Raspberry Pi with a Hifiberry DigiIO, and the source stops the datastream. What happens then is that readi waits for about 3 seconds, then returns with EIO.
Shoud this be possible? What does it actually mean?
I would like to handle the situation so that things can just continue when the signal comes back. After starting the spdif stream again I have tried just readi again but that's no good. I also tried prepare(), but that gives EBUSY. Should I try recover()?
One problem here is that I don't have a card that behaves like this myself, so testing many different things is quite slow. Any ideas to narrow down the number of things to try would be highly appreciated!

ALSA links not working

The links to the ALSA website in the readme and crate-level documentation do not work. Looking at the code this is because it says http://http:// instead of just http://.

Turn name parameter for Seq::open into an Option

Seq::open requires a name parameter which (according to ALSA documentation) should usually be "default". I do not know when it does not need to be "default".

Maybe the parameter could be turned into an Option<&CStr> instead, and if None is passed, we can use the following without an allocation or runtime check:

CStr::from_bytes_with_nul_unchecked(b"default\0").

Setter functions not requiring mutable references

Consider the following example:

use alsa::seq::{Addr, PortSubscribe};

fn foo(sub: &PortSubscribe) {
    sub.set_dest(Addr {
        client: 123,
        port: 45,
    });
}

fn main() {
    let sub = PortSubscribe::empty().unwrap();
    println!("{:?}", sub.get_dest());
    foo(&sub);
    println!("{:?}", sub.get_dest());
}

This just feels unsound to me, mutating the state of ALSA types without requiring mutable references. PortSubscribe is not the only one affected by this, there are dozens of setter functions in this crate without proper mutability constraints.

warnings when using rust nightly

On nightly there are some warnings on array bound checks:

Compiling alsa v0.1.3 (https://github.com/diwic/alsa-rs#7bc4f794)
warning: this expression will panic at run-time
  --> /home/rbalt/.cargo/git/checkouts/alsa-rs-931cd3713a30a710/master/src/chmap.rs:74:49
   |
74 |         unsafe { slice::from_raw_parts_mut(&mut (*self.0).pos[0], (*self.0).channels as usize) }
   |                                                 ^^^^^^^^^^^^^^^^ index out of bounds: the len is 0 but the index is 0

warning: this expression will panic at run-time
  --> /home/rbalt/.cargo/git/checkouts/alsa-rs-931cd3713a30a710/master/src/chmap.rs:77:45
   |
77 |         unsafe { slice::from_raw_parts(&mut (*self.0).pos[0], (*self.0).channels as usize) }
   |                                             ^^^^^^^^^^^^^^^^ index out of bounds: the len is 0 but the index is 0

Not sure if we need to suppress the warning or changes in the way we use ffi?

`alsa::seq::EventData::get_data` feels unsafe

I'm rewriting a C utility in Rust using alsa, and when looking at alsa::seq::EventData::get_data's content it feels like it is meant to do an unchecked cast. Shouldn't it be marked as unsafe? It feels inherently unsafe to me.

Additionally, you tell us "Donโ€™t use these directly, use generic methods on Event instead". It seems like you tell this so we don't miss-use get_data, as using it in the wrong context can lead to UB, if I understood correctly. So making it unsafe feels right to me.

Wrap snd_seq_control_queue

This is a follow-up after #16, because I took some time now to look at it. And I'm impressed, the current version contains almost everything that I needed, awesome work! ๐Ÿ‘

I'm missing only one function: snd_seq_control_queue. Actually I'm using snd_seq_start_queue and snd_seq_stop_queue, but those are defined as macros in the original API (wrapping snd_seq_control_queue). Maybe you can create functions for them also.

Error: explicit destructor calls not allowed

When using pcm.drop() the Rust compilers fails with:

error[E0040]: explicit use of destructor method

     |
1011 |                 { let pcm = self.0.as_mut().unwrap(); pcm.drop().unwrap(); }
     |                                                           ^^^^ explicit destructor calls not allowed

Avoid panic if card gives bad state

I got a bug report on my DSP project, where it panics when reading the state of a pcm.
The panic comes from here : https://github.com/diwic/alsa-rs/blob/master/src/pcm.rs#L159
I'm guessing the card returns an invalid value for the state, but it doesn't happen with any of the hardware I have so I can't check that.
Anyway, would it be an option to add an "Invalid" or "Unknown" state variant to avoid a panic with misbehaving hardware? Or let state() return a Result?
I can implement something and make a PR, but let's agree on the ifs and how's first :)

Suggestion: Add ability to create IO instances from PCMs generically

Hi! I was trying to generically create an instance of the IO struct from an instance of PCM, depending on which format is being used. This is currently not easily possible, as something like

let io = pcm.io::<u32>()?;

is not possible. The reason is, of course, that the different PCM::io_* methods perform checks based on instances of the Format enum here.

So I ended up implementing a trait like this:

use alsa::pcm::{IO, PCM};

trait IoFromPcm: Copy {
    fn io_from_pcm<'a>(pcm: &'a PCM) -> alsa::Result<IO<Self>>;
}

impl IoFromPcm for u8 {
    fn io_from_pcm<'a>(pcm: &'a PCM) -> alsa::Result<IO<Self>> {
        pcm.io_u8()
    }
}

impl IoFromPcm for i8 {
    fn io_from_pcm<'a>(pcm: &'a PCM) -> alsa::Result<IO<Self>> {
        pcm.io_i8()
    }
}

// and so on for u16, i16, u32, i32, f32, and f64

and then doing something like this in my application code:

fn play_something<T: IoFromPcm>(&self, buf: &[T]) -> alsa::Result<()> {
    let io = T::io_from_pcm(&self.pcm)?;
    io.writei(&buf)?;

    // ...
}

(The above is greatly abridged, not sure if that would really compile, but I think you get the idea).

Maybe it would be cool to add a similar mechanism to the library, to make it easier to dynamically choose a format for the IO instance?

Selecting timestamp type

Hi @diwic!
Thanks a lot for the great work on this crate, it's really useful.

For the MultiDSP project, I'm researching the best way to implement an asynchronous resampler that'll keep multiple sound cards in sync.

The best way seems to be leveraging the PCM status delay, avail and timestamps.
It is already possible to query that today but the timestamps seem to always of the default type: DMA.
For the use case of sound card synchronization, the link time and analog times are useful as well.
Documentation: https://www.kernel.org/doc/html/latest/sound/designs/timestamping.html

I rewrote in Rust alsa_time.c from alsa-lib for experimentation and am now testing from that.

Is timestamp type support something you're interested adding?
If I should implement it myself, would you have recommendations?

Missing snd_ctl_elem_id_set_*

I noticed that the snd_ctl_elem_id_set_* functions are missing while the snd_ctl_elem_id_get_* functions are present. Do you have plans to add them?

32/64 bit support

I was having some issues with setting the volume via the Mixer api, and after some head scratching realised that my user space was 32bit, so all my i64 volume values were overflowing.

Would it make sense to switch to isize instead of i64 - where the underlying api uses c_long?
Like at:

alsa-rs/src/mixer.rs

Lines 339 to 341 in 8666041

pub fn set_playback_volume_all(&self, value: i64) -> Result<()> {
acheck!(snd_mixer_selem_set_playback_volume_all(self.handle, value as c_long)).map(|_| ())
}

Share PCM between multiple threads

Hi @diwic !

I'd like to access PCMs from multiple threads (at least two) in order to:

  • Only read/write buffers at real-time priority
  • Gather PCM Status for timestamp / avail data at a specified frequency and at the highest real-time priority. The frequency should not depend on capture or playback frame sizes.

In order to do that, there will be three threads.

  1. Capture thread
  2. Playback thread
  3. Timestamp/avail status gathering thread.

Therefore, both capture and playback PCMs need to be shared with the status gathering thread, that'll periodically adjust an asynchronous resampler ratio.

In alsa-lib tests, the pcm-multi-thread.c example shows how it is possible in C.
It's simple, a single static snd_pcm_t *pcm is declared on top and all threads call methods on it.

Would it be possible to do that with alsa-rs?
Right now, I get this error:

error[E0277]: the trait bound `*mut alsa_sys::snd_pcm_t: std::marker::Sync` is not satisfied in `&alsa::PCM`
   --> src/alsa_audio_time.rs:155:9
    |
155 |         thread::spawn(|| {
    |         ^^^^^^^^^^^^^ `*mut alsa_sys::snd_pcm_t` cannot be shared between threads safely

Link and unlink PCMs

Hi @diwic :)
Also for the MultiDSP project, it would be useful to gain the ability to link/unlink PCMs.
It's a feature which helps to reach the lowest latency without xrun when capturing then playing at the same sample rate from ADC/DAC running from the same master clock + PLL or crystal.
The way it works is by preparing and starting PCMs to their running state at the same time.

snd_pcm_link
snd_pcm_unlink

I haven't come across hardware where it is applicable but it is also possible to link more than two in a group.

Please, Need example

Please, I very need example "Capture and Playback" (Stereo Microphone) in infinity loop.

test pcm::playback_to_default sometimes fails

This is the result of running cargo test (on my PR branch, but I didn't change anything outside the seq module), although sometimes this test passes:

failures:

---- pcm::playback_to_default stdout ----
	PCM status: Prepared, HwParams(channels: Ok(1), rate: Ok(44100) Hz, format: Ok(S16LE), access: Ok(RWInterleaved), period size: Ok(2048) frames, buffer size: Ok(2097152) frames)
== PCM dump ==
ALSA <-> PulseAudio PCM I/O Plugin
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 1
  rate         : 44100
  exact rate   : 44100 (44100/1)
  msbits       : 16
  buffer_size  : 2097152
  period_size  : 2048
  period_time  : 46439
  tstamp_mode  : NONE
  tstamp_type  : GETTIMEOFDAY
  period_step  : 1
  avail_min    : 2048
  period_event : 0
  start_threshold  : 1
  stop_threshold   : 2097152
  silence_threshold: 0
  silence_size : 0
  boundary     : 4611686018427387904

thread 'pcm::playback_to_default' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Some("snd_pcm_writei"), -32)', /checkout/src/libcore/result.rs:859
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: <core::result::Result<T, E>>::unwrap
             at /checkout/src/libcore/result.rs:737
   1: alsa::pcm::playback_to_default
             at ./src/pcm.rs:750
   2: <F as test::FnBox<T>>::call_box
             at /checkout/src/libtest/lib.rs:1368
             at /checkout/src/libcore/ops.rs:2606
             at /checkout/src/libtest/lib.rs:140
   3: std::panicking::try::do_call
             at /checkout/src/libtest/lib.rs:1314
             at /checkout/src/libstd/panic.rs:296
             at /checkout/src/libstd/panicking.rs:454
   4: __rust_maybe_catch_panic
             at /checkout/src/libpanic_unwind/lib.rs:98
   5: std::panicking::try::do_call
             at /checkout/src/libstd/panicking.rs:433
             at /checkout/src/libstd/panic.rs:361
             at /checkout/src/libtest/lib.rs:1313
             at /checkout/src/libstd/panic.rs:296
             at /checkout/src/libstd/panicking.rs:454
   6: __rust_maybe_catch_panic
             at /checkout/src/libpanic_unwind/lib.rs:98
   7: <F as alloc::boxed::FnBox<A>>::call_box
             at /checkout/src/libstd/panicking.rs:433
             at /checkout/src/libstd/panic.rs:361
             at /checkout/src/libstd/thread/mod.rs:360
             at /checkout/src/liballoc/boxed.rs:640
   8: std::sys::imp::thread::Thread::new::thread_start
             at /checkout/src/liballoc/boxed.rs:650
             at /checkout/src/libstd/sys_common/thread.rs:21
             at /checkout/src/libstd/sys/unix/thread.rs:84
   9: start_thread
  10: clone


failures:
    pcm::playback_to_default

test result: FAILED. 20 passed; 1 failed; 0 ignored; 0 measured

How to use SelemId::new?

Hello!
I just started learning Rust and Alsa and I am trying to access my audio interface (Focusrite Scarlett 18i8 2.gen).
My goal is to have a simple Rust program that can make changes to the interfaces mixer (e.g. muting channel 1, ...).

I started with the following lines to access the interface:

let mixer: Mixer  = Mixer::new("hw:3", false).unwrap();
let sid: SelemId    = SelemId::new("????", 0);
let selem: Selem = mixer.find_selem(&sid).expect("Coundn't find SelemId");

The code fails trying to find the selem. I dont know which values are expected of the SelemId.
Is this the name/index of an mixer element?
Where can I get these infos?

Thank you in advance!

Release new version

It's been a while since you've released v0.5.0 and there have been at least a couple additions and fixes since then. A new release would be greatly appreciated. Maybe v0.5.1? Or whatever versioning scheme you're using? In my mind the next release wouldn't really be a major release but that's completely up to you.

test failed in fedora copr

https://download.copr.fedorainfracloud.org/results/remilauzier/zemeroth/fedora-rawhide-x86_64/02304631-rust-alsa/builder-live.log.gz

failures:

---- src/pcm.rs - pcm (line 6) stdout ----
Test executable failed (exit code 101).

stderr:
ALSA lib confmisc.c:855:(parse_card) cannot find card '0'
ALSA lib conf.c:5111:(_snd_config_evaluate) function snd_func_card_inum returned error: No such file or directory
ALSA lib confmisc.c:422:(snd_func_concat) error evaluating strings
ALSA lib conf.c:5111:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1334:(snd_func_refer) error evaluating name
ALSA lib conf.c:5111:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5599:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM default
thread 'main' panicked at 'called Result::unwrap() on an Err value: Error("snd_pcm_open", Sys(ENOENT))', src/pcm.rs:8:59
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Build error on arm-unknown-linux-musleabihf

Compiling alsa v0.2.1
     Running `rustc --crate-name alsa /home/rust/.cargo/registry/src/github.com-1ecc6299db9ec823/alsa-0.2.1/src/lib.rs --color always --crate-type lib --emit=dep-info,link -C opt-level=3 -C metadata=976c596c68b6c14b -C extra-filename=-976c596c68b6c14b --out-dir /home/rust/librespot/target/arm-unknown-linux-musleabihf/release/deps --target arm-unknown-linux-musleabihf -L dependency=/home/rust/librespot/target/arm-unknown-linux-musleabihf/release/deps -L dependency=/home/rust/librespot/target/release/deps --extern alsa_sys=/home/rust/librespot/target/arm-unknown-linux-musleabihf/release/deps/libalsa_sys-4c26c22d6bab838f.rlib --extern bitflags=/home/rust/librespot/target/arm-unknown-linux-musleabihf/release/deps/libbitflags-d29977ccc17621f8.rlib --extern libc=/home/rust/librespot/target/arm-unknown-linux-musleabihf/release/deps/liblibc-989e9cf5fcbc9d40.rlib --extern nix=/home/rust/librespot/target/arm-unknown-linux-musleabihf/release/deps/libnix-1ff35c4c0a502aed.rlib --cap-lints allow -L native=/usr/lib/arm-linux-gnueabihf`
error[E0308]: mismatched types
   --> /home/rust/.cargo/registry/src/github.com-1ecc6299db9ec823/alsa-0.2.1/src/pcm_direct.rs:325:82
    |
325 |             mem: DriverMemory::new(fd, (bufsize as usize) * (channels as usize), info.offset, true)?,
    |                                                                                  ^^^^^^^^^^^ expected i64, found i32
help: you can cast an `i32` to `i64`, which will sign-extend the source value
    |
325 |             mem: DriverMemory::new(fd, (bufsize as usize) * (channels as usize), info.offset.into(), true)?,
    |                                                                                  ^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: Could not compile `alsa`.

I could fix this error by changing the line 325 of pcm_direct.rs to:
mem: DriverMemory::new(fd, (bufsize as usize) * (channels as usize), info.offset as i64, true)?

Did others experience the same issue and does this error occur on other platforms as well?

Passing PCM handles between threads

I'm not very familiar with the ALSA API, but the way I interpret http://www.alsa-project.org/main/index.php/SMP_Design, it seems that it is possible to send PCM handles across thread boundaries?

In a very simple application with a single audio thread, I'd love to be able to open the PCM device in the main thread, that way I don't have to propagate open/hwparam errors/unwraps back.

However, since *mut alsa_sys::snd_pcm_t isn't Send, neither is alsa::PCM, among other things because no explicit Send implementation has been added.

While PCM is definitely not Sync, I think Send fits?

Contributing

Sorry for opening an issue for this, but I wanted to reach out to discuss how I might be able to contribute to this crate in terms of documentation and code. If you're on discord, my username is naftulikay, if email works better, you can reach me at me AT my first name DOT w t f. Tried emailing at your ubuntu email address but it wouldn't route through. I'm also @naftulikay on twitter if that's a preferred method of communication.

Best practice - SelemId and Mixer lifetimes

I'm quite new to rust, and was wondering what the best way to achieve the following is?
As the SelemId is borrowed from the Mixer, there isn't much I can do correct?

fn get_selem(card: &str, mixer: &str) -> Result<(mixer::Selem), Box<Error>> {
    let selem_id = mixer::SelemId::new(mixer, 0);
    let mixer = mixer::Mixer::new(card, false)?;
    let selem = mixer.find_selem(&selem_id)?;

    Ok((selem))
}
error[E0106]: missing lifetime specifier
  --> playback/src/mixer/alsamixer.rs:12:50
   |
12 | fn get_selem(card: &str, mixer: &str) -> Result<(mixer::Selem), Box<Error>> {
   |                                                  ^^^^^^^^^^^^ expected lifetime parameter
   |
   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `card` or `mixer`

set volume: do we need mixer interface?

I've been looking at the alsa api to use the mixer to set volume of individual channels. Do we need to add a wrapper for the snd_mixer_* and/or snd_mixer_selem_*?

Support Creating an Hctl from a Ctl via snd_hctl_open_ctl

I'm currently working on a project that uses this crate heavily, much thanks for all the hard work.

I am currently using the following logic to obtain a HCtl instance:

use alsa::{Ctl, HCtl};
use alsa::card::{Iter as CardIter};

let mut card_iter = CardIter::new();

while let Some(Ok(card)) = card_iter.next() {
    let ctl = Ctl::from_card(&card, true).unwrap();
    let hctl = HCtl::new(format!("hw:{}", card.get_index()).as_str(), true).unwrap();

    // do work
}

Fetching a HCtl instance from the device name is error-prone perhaps, as there's no direct way to go from a Card instance to an HCtl instance. It's possible to go from Card to Ctl using Ctl::from_card, but no way to go from either Card or Ctl to HCtl.

In the underlying alsa-sys crate, and thus the C library, snd_hctl_open_ctl allows creation of a snd_hctl_t handle from an existing snd_ctl_t. Therefore, it shouldn't be too difficult to implement a method like HCtl::from_ctl to make it easier to get a HCtl from a Ctl.

I may be able to contribute some work here, but it will have to wait a few days at best.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.