Skip to content

nRF: PWMAudioOut: fix half-speed playback of stereo samples #2364

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

Merged
merged 1 commit into from
Dec 9, 2019

Conversation

jepler
Copy link

@jepler jepler commented Dec 9, 2019

The "spacing" of "buffer structure" is confusing, use the "channel count" instead.

Testing performed on nrf52840 feather:

Play stereo and mono, 8- and 16-bit, 8kHz RawSamples representing 333.33Hz square waves.

Use both mono and stereo PWMAudioOut instances.

Scope the RC-filtered signal and use the scope's frequency measurement function, verify the frequency is 333 or 334Hz in all tested cases.

In the "stereo output" cases, verify both the L and R channels. Verify the output amplitude is the same in both channels.

In the "stereo output" cases, run a second test where the L channel's amplitude is attenuated 50%. Verify the output amplitude is correct in each channel.

import array
try:
    import audiobusio
except ImportError:
    pass
try:
    import audiopwmio
except ImportError:
    pass
import audiocore
import board
import time

values = {
    'b': (-128, 127),
    'B': (0, 255),
    'h': (-32768, 32767),
    'H': (0, 65535),
}

# Should play an audio sample at 333Hz (=8000/24)
def go(audio, at = 'h', channel_count = 1, attenuate_left=False):
    wave = array.array(at, [values[at][0]]) * channel_count * 24
    for i in range(len(wave)//2, len(wave)):
        wave[i] = values[at][1]
    if channel_count > 1 and attenuate_left:
        for i in range(0, len(wave), channel_count):
            wave[i] //= 2
    print(wave)

    wave_sample = audiocore.RawSample(wave, channel_count = channel_count)

    audio.play(wave_sample, loop=True)
    time.sleep(1)
    audio.stop()

def go_i2s(at='h', channel_count=1, attenuate_left=False):
    with audiobusio.I2SOut(bit_clock=board.D6, word_select=board.D9, data=board.D10) as audio:
        go(audio, at, channel_count, attenuate_left)

def go_pwm(at='h', channel_count=1, attenuate_left=False):
    with audiopwmio.PWMAudioOut(board.D2) as audio:
        go(audio, at, channel_count, attenuate_left)

def go_pwm_stereo(at='h', channel_count=1, attenuate_left=False):
    with audiopwmio.PWMAudioOut(board.D2, right_channel=board.D5) as audio:
        go(audio, at, channel_count, attenuate_left)

The "spacing" of "buffer structure" is confusing, use the "channel count"
instead.

Testing performed on nrf52840 feather:

Play stereo and mono, 8- and 16-bit, 8kHz RawSamples representing 333.33Hz
square waves.

Use both mono and stereo PWMAudioOut instances.

Scope the RC-filtered signal and use the scope's frequency
measurement function, verify the frequency is 333 or 334Hz in all tested
cases.

In the "stereo output" cases, verify both the L and R channels.  Verify
the output amplitude is the same in both channels.

In the "stereo output" cases, run a second test where the L channel's
amplitude is attenuated 50%. Verify the output amplitude is correct
in each channel.
@tannewt tannewt self-requested a review December 9, 2019 22:20
@tannewt tannewt added this to the 5.x.x - Bug Fixes milestone Dec 9, 2019
Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet! Thank you!

@tannewt tannewt merged commit 2379cd9 into adafruit:master Dec 9, 2019
@jepler jepler deleted the nrf-stereo-rate branch November 3, 2021 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants