Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Stream to hold a generic reference to PortAudio #120

Closed
JustAPerson opened this issue Jan 19, 2016 · 6 comments
Closed

Change Stream to hold a generic reference to PortAudio #120

JustAPerson opened this issue Jan 19, 2016 · 6 comments

Comments

@JustAPerson
Copy link

Currently Stream requires a &'a PortAudio. This prevents placing both into the same structure. Perhaps this relationship could be changed such that Stream requires a T where T: Deref<PortAudio> such that you could use an Rc<PortAudio> instead, allowing greater flexibility when structuring code.

@mitchmindtree
Copy link
Member

Hmmm I think it might be fine to just store an Rc<PortAudio> directly instead, but I'd like to avoid using a shared pointer if at all possible. Thanks for posting the issue! I'd like to have a think about this some more before making any changes.

From what I can tell, it seems like you just want a single Stream and that you'd like to group the PortAudio's functionality along with the Stream in this single structure? In the mean-time perhaps you could use lazy_static! in order to declare a single, global PortAudio instance with a 'static lifetime, which you could then use to spawn your Stream. This way, your structure could still access and wrap the functionality of both, while owning a Stream<'static> and in turn also avoiding the need for a lifetime parameter in your structure. Let me know how this goes!

@tiborgats
Copy link

The lazy_static! solution works fine, however it forces me to use .unwrap() instead of try!(). My only problem with this solution is that in this way I cannot handle errors (if pa::PortAudio::new() returns one). I really would like to avoid any panic! in my program (I like user friendly GUI messages, and proper logging of errors).

@mitchmindtree
Copy link
Member

@tiborgats thanks for pitching in!

I think I'm struggling a bit to see why it forces you to use .unwrap() - would you mind posting a snippet with your PortAudio initialisation and how you spawn the Stream? I definitely don't want you to have to panic! on errors!

@tiborgats
Copy link

Currently I have one module dealing with audio, and I have these declarations there:

pub struct SoundInterface<'a> {
    sample_rate: u32,
    channel_count: u16,
    stream: pa::Stream<'a, pa::NonBlocking, pa::stream::Output<SampleOutput>>,
...
}

impl<'a> SoundInterface<'a> {
    pub fn new(sample_rate: u32,
               channel_count: u16,
               mut generator: Box<SoundGenerator>)
               -> SoundResult<SoundInterface<'a>> {
        lazy_static! {
            static ref PORTAUDIO: pa::PortAudio = pa::PortAudio::new().unwrap();
        }
        let mut settings = try!(PORTAUDIO.default_output_stream_settings(channel_count as i32,
                                                                         sample_rate as f64,
                                                                         FRAMES_PER_BUFFER));
...
    }
...
}

The above works fine. But if I try to do this:

lazy_static! {
    static ref PORTAUDIO: pa::PortAudio = try!(pa::PortAudio::new());
}

I get the following error:

<std macros>:5:8: 6:42 error: mismatched types:
 expected `portaudio::PortAudio`,
    found `core::result::Result<_, _>`
(expected struct `portaudio::PortAudio`,
    found enum `core::result::Result`) [E0308]
<std macros>:5 return $ crate:: result:: Result:: Err (
<std macros>:6 $ crate:: convert:: From:: from ( err ) ) } } )
src/sound/interface.rs:39:48: 39:74 note: in this expansion of try! (defined in <std macros>)
<lazy_static macros>:4:1: 5:71 note: in this expansion of lazy_static! (defined in <lazy_static macros>)
src/sound/interface.rs:38:9: 41:10 note: in this expansion of lazy_static! (defined in <lazy_static macros>)
<std macros>:5:8: 6:42 help: run `rustc --explain E0308` to see a detailed explanation

@mitchmindtree
Copy link
Member

@tiborgats ahh I see. I haven't had a chance to put too much thought into this yet, but I guess one alternative would be to make PORTAUDIO a Result<pa::PortAudio, pa::Error>? There might be a better way though, I'll put some more thought into this when I get some more time.

@tiborgats
Copy link

How about adding a lifetime parameter to PortAudio (same way as having one for Stream), so I can set it to match my struct's lifetime? And thus we do not need static declaration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants