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

Both blocking and non-blocking examples use 100% CPU #124

Closed
theovosse opened this issue Feb 11, 2016 · 6 comments
Closed

Both blocking and non-blocking examples use 100% CPU #124

theovosse opened this issue Feb 11, 2016 · 6 comments

Comments

@theovosse
Copy link

When I run the two streaming programs from the examples directory, they take 100% of the CPU. When I limit it to just reading the input, the same happens, and it seems the main loop just gets 0 bytes and keeps looping like mad until finally a full buffer arrives. Is that a problem in rust-portaudio or in the lower portaudio library?

@mitchmindtree
Copy link
Member

Hmmm I'm not sure. So this only happens for streams that are either duplex or input (i.e. trying to stream data from some input device)? Do you get the same issues when running the sine or saw examples? Or are they fine?

What platform are you on? Do you know what the default input device is on your system? Could you perhaps post all of the device info etc that prints to console at the start of the non_blocking.rs example (i.e. here)? And maybe also for the devices.rs example if you can?

Sorry about all the questions - hopefully we can get to the bottom of it 👍

@theovosse
Copy link
Author

Ok, here we go.

  • sine.rs uses about 4%-5% of one core. So yes, it only seems to happen when reading input (regardless of the device, by the way).
  • Platform: OSX 10.11.3, Rust 1.6, rust-portaudio 0.6.2, brew portaudio 19.20140130.
  • Output from devices.rs (I've removed the list of supported sample rates, which oddly enough include 192kHz, even though the devices don't support that).
Number of devices = 5
--------------------------------------- DeviceIndex(0)
DeviceInfo {
    struct_version: 2,
    name: "Built-in Microph",
    host_api: 0,
    max_input_channels: 2,
    max_output_channels: 0,
    default_low_input_latency: 0.00199546485260771,
    default_low_output_latency: 0.01,
    default_high_input_latency: 0.012154195011337868,
    default_high_output_latency: 0.1,
    default_sample_rate: 44100
}
Supported standard sample rates for half-duplex 16-bit 2 channel input:...
Supported standard sample rates for half-duplex 16-bit 0 channel output:
Supported standard sample rates for full-duplex 16-bit 2 channel input, 0 channel output:
--------------------------------------- DeviceIndex(1)
DeviceInfo {
    struct_version: 2,
    name: "Built-in Input",
    host_api: 0,
    max_input_channels: 2,
    max_output_channels: 0,
    default_low_input_latency: 0.00199546485260771,
    default_low_output_latency: 0.01,
    default_high_input_latency: 0.012154195011337868,
    default_high_output_latency: 0.1,
    default_sample_rate: 44100
}
Supported standard sample rates for half-duplex 16-bit 2 channel input:...
Supported standard sample rates for half-duplex 16-bit 0 channel output:
Supported standard sample rates for full-duplex 16-bit 2 channel input, 0 channel output:
--------------------------------------- DeviceIndex(2)
DeviceInfo {
    struct_version: 2,
    name: "Built-in Output",
    host_api: 0,
    max_input_channels: 0,
    max_output_channels: 2,
    default_low_input_latency: 0.01,
    default_low_output_latency: 0.004149659863945578,
    default_high_input_latency: 0.1,
    default_high_output_latency: 0.014308390022675737,
    default_sample_rate: 44100
}
Supported standard sample rates for half-duplex 16-bit 0 channel input:
Supported standard sample rates for half-duplex 16-bit 2 channel output:...
Supported standard sample rates for full-duplex 16-bit 0 channel input, 2 channel output:
--------------------------------------- DeviceIndex(3)
DeviceInfo {
    struct_version: 2,
    name: "US-122L (Bit Accurate)",
    host_api: 0,
    max_input_channels: 2,
    max_output_channels: 2,
    default_low_input_latency: 0.01,
    default_low_output_latency: 0.017414965986394557,
    default_high_input_latency: 0.1,
    default_high_output_latency: 0.021768707482993196,
    default_sample_rate: 44100
}
Supported standard sample rates for half-duplex 16-bit 2 channel input:...
Supported standard sample rates for half-duplex 16-bit 2 channel output:...
Supported standard sample rates for full-duplex 16-bit 2 channel input, 2 channel output:...
--------------------------------------- DeviceIndex(4)
DeviceInfo {
    struct_version: 2,
    name: "US-122L (Core Audio)",
    host_api: 0,
    max_input_channels: 2,
    max_output_channels: 2,
    default_low_input_latency: 0.01,
    default_low_output_latency: 0.018412698412698412,
    default_high_input_latency: 0.1,
    default_high_output_latency: 0.02857142857142857,
    default_sample_rate: 44100
}
Supported standard sample rates for half-duplex 16-bit 2 channel input: ...
Supported standard sample rates for half-duplex 16-bit 2 channel output: ...
Supported standard sample rates for full-duplex 16-bit 2 channel input, 2 channel output: ...
  • Output from non_blocking.rs
PortAudio:
version: 1899
version text: Ok("PortAudio V19-devel (built Feb  6 2016 20:53:16)")
host count: 1
default host: Some(
    HostApiInfo {
        struct_version: 1,
        host_type: CoreAudio,
        name: "Core Audio",
        device_count: 5,
        default_input_device: DeviceIndex(
            0
        ),
        default_output_device: DeviceIndex(
            4
        )
    }
)
Default input device info: DeviceInfo {
    struct_version: 2,
    name: "Built-in Microph",
    host_api: 0,
    max_input_channels: 2,
    max_output_channels: 0,
    default_low_input_latency: 0.00199546485260771,
    default_low_output_latency: 0.01,
    default_high_input_latency: 0.012154195011337868,
    default_high_output_latency: 0.1,
    default_sample_rate: 44100
}
Default output device info: DeviceInfo {
    struct_version: 2,
    name: "US-122L (Core Audio)",
    host_api: 0,
    max_input_channels: 2,
    max_output_channels: 2,
    default_low_input_latency: 0.01,
    default_low_output_latency: 0.018412698412698412,
    default_high_input_latency: 0.1,
    default_high_output_latency: 0.02857142857142857,
    default_sample_rate: 44100
}
count_down: 3
count_down: 2.99424217700016
etc.

Sorry about all the questions - hopefully we can get to the bottom of it 👍

Not at all. I'd like to do some audio stuff in rust, so it would be good if we could get to the bottom of this. Perhaps I should try some examples in C too...

Edit: I did manage to get reading from an input stream down to about 4% by adding a sleep function. So I can continue working on my little experiment, but it's not idea

@limeburst
Copy link
Contributor

This is caused by the busy loop checking the stream state.

In practice, the stream state doesn't need to be checked as fast as possible. The examples can be modified to run more efficiently, as you found out with the sleep function 😄

FYFI, in asynchronous mode, PortAudio will periodically execute the callback function at the right time, calculating the interval from the given sample rate and buffer state while the stream is active.

@theovosse
Copy link
Author

FYFI

What does that mean?

@ulfmagnetics
Copy link

@flwrd: FYFI == "For your further information", I believe

@theovosse
Copy link
Author

Ok, this doesn't go anywhere.

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

4 participants