cpal icon indicating copy to clipboard operation
cpal copied to clipboard

macOS speaker data doesnt flow

Open Jerolivine opened this issue 6 months ago • 9 comments

I am using the code block to see if i am able to retrieve speaker data. It works fine with windows but the same code doesnt work for macOS.

Is there some arrangement can be done to make it work for macOS such as accessibility or any code changes that i share below?

use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{Host, Stream, StreamConfig, SupportedStreamConfig};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
        let host = cpal::default_host();

     let device = host
         .default_output_device()
         .ok_or_else(|| anyhow::anyhow!("no output device available"))?;

     let mut supported_configs_range = device
         .supported_output_configs()
         .map_err(|err| anyhow::anyhow!("error while querying configs: {}", err))?;

     let supported_config: SupportedStreamConfig = supported_configs_range
         .next()
         .ok_or_else(|| anyhow::anyhow!("no supported output config"))?
         .with_max_sample_rate();
    
     let err_fn = move |err| {
         eprintln!("an error occurred on stream: {}", err);
     };

     println!("{}",supported_config.sample_format());

     let stream = match supported_config.sample_format() {
                cpal::SampleFormat::I8
         | cpal::SampleFormat::I16
         | cpal::SampleFormat::I32
         | cpal::SampleFormat::I64
         | cpal::SampleFormat::U8
         | cpal::SampleFormat::U16
         | cpal::SampleFormat::U32
         | cpal::SampleFormat::U64
                 | cpal::SampleFormat::F32 => device.build_input_stream(
                     &supported_config.into(),
                     move |data:&[f32], _: &_| {
                         println!("data flows.")
                     },
                     err_fn,
                     None
                 )?,
     _ => {panic!("sample format");}
     };

    
    // Start the stream
    stream.play()?;
    
    // Keep the application running to keep receiving data
    std::thread::sleep(std::time::Duration::from_secs(10));
    
    Ok(())
}

Jerolivine avatar Jun 17 '25 19:06 Jerolivine

I had similar issues with MacOS, default devices were not recognized properly. Made some fixes for myself but have not had time yet to look into it too much to make a pr. You can check the changes I made here if that is for any help: https://github.com/MatiasHiltunen/cpal/blob/master/src/host/coreaudio/macos/enumerate.rs

MatiasHiltunen avatar Jun 20 '25 03:06 MatiasHiltunen

I tried to import your git repository to my cargo.toml, but looks like i still have the same problem @MatiasHiltunen . What is the situation on your side? Could i ask you to check on your machine ?

Jerolivine avatar Jun 20 '25 08:06 Jerolivine

Can you run the spectrogram example from my repo?

MatiasHiltunen avatar Jun 20 '25 08:06 MatiasHiltunen

hmm. In the console i see some colors pink to white and somme blacks too. @MatiasHiltunen

Jerolivine avatar Jun 20 '25 08:06 Jerolivine

by thte way your spectrogram example is taking microphone device. What i am trying to achieve is to get the speaker. @MatiasHiltunen Is there anything i miss to spesify the device shoulud be speaker ?

Jerolivine avatar Jun 20 '25 09:06 Jerolivine

Oh, right! I'll try to check this when I have access to my mac, currently have only windows device :)

MatiasHiltunen avatar Jun 20 '25 09:06 MatiasHiltunen

I think the problem is that on windows wasapi allows loopback recording but CoreAudio's loopback is apparently not supported with cpal yet. I think it might be possible to add support for it though, fe. AudioCap has working implementation with it. Perhaps some virtual driver could be useful here?

MatiasHiltunen avatar Jun 22 '25 21:06 MatiasHiltunen

This issue was resolved for me moving from 0.15 -> 0.16

sarosh avatar Jun 27 '25 18:06 sarosh

@sarosh are you able to retrieve speaker audio with macOS ?

Jerolivine avatar Jun 30 '25 09:06 Jerolivine

@Jerolivine Just to be clear, in your sample code you try to build a new input stream from output device, would a simple feedback without the actual loopback support work in your case? Like the feedback.rs from examples but instead of input to output you'd feed the output to input. Not sure if that would work but might be worth to try? I have drafted loopback support for coreaudio based on AudioCap's solution but have not had time to complete it yet.

MatiasHiltunen avatar Jul 01 '25 10:07 MatiasHiltunen

I was unable to recreate this issue on my MacBook Air M1. In fact, I've been able to retrieve audio from various microphones including professional audio interfaces and built-in Devices. Maybe you need to perform stdout() in order to ensure you can see println!("data flows.");.

My understand was that the issue was not being able to see this print function. If this isn't the case, please let me know, and I'd be happy to work with you to resolve this if it hasn't been already.

wgibbs-rs avatar Jul 31 '25 18:07 wgibbs-rs

Closing as multiple comments lead to believe this is since fixed on v0.16 and with the soon-to-be-released v0.17 that also support macOS loopback. Feel free to reopen if it's still not working on latest master.

roderickvd avatar Dec 10 '25 20:12 roderickvd