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

Using __iter__ to retrigger the oscillators can cause unexpected problems #2

Open
ali1234 opened this issue May 13, 2022 · 0 comments

Comments

@ali1234
Copy link

ali1234 commented May 13, 2022

Iterable objects usually just return self from the __iter__ method, and quite a lot of code expects this to be the case. Resetting the oscillator there can lead to surprising results, for example:

import miniaudio
import numpy as np

from oscillators import SineOscillator


def stream_pcm(source):
    required_frames = yield b""  # generator initialization
    while True:
        buf = np.fromiter(source, dtype=float, count=required_frames)*32767
        required_frames = yield buf.astype(np.int16).tobytes()


if __name__ == '__main__':
    sample_rate = 44100

    with miniaudio.PlaybackDevice(output_format=miniaudio.SampleFormat.SIGNED16,
                              nchannels=1, sample_rate=sample_rate) as device:

        source = SineOscillator(sample_rate=sample_rate)
        stream = stream_pcm(source)
        next(stream)  # start the generator
        device.start(stream)
        input("Audio file playing in the background. Enter to stop playback: ")

It turns out that np.fromiter() calls iter() on whatever you pass it before calling next() count times, so the oscillator gets reset back to zero on every buffer callback. This causes glitchy playback.

An easy work around is just to hide the custom __iter__ method with a wrapper:

def wrapper(source):
    yield from source

I think it would be better to have an explicit trigger or reset method, rather than re-purposing __iter__ for this.

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

1 participant