Skip to content

Recording/Getting samples: interaction with CODAL for sound recording #49

@jaustin

Description

@jaustin

...transferring from the past private Repo from when V2 was still not announced....
@jaustin commented on Mon Sep 21 2020

We'd like a few Python code examples of how the user could record samples from the microphone and then play them back in the style of a parrot (eg listen until the buffer is full, or there's a silence)

@dpgeorge was going to have a go at putting forward a few different sample models and @microbit-giles and @microbit-carlos could we please also contribute here things from our API prototyping?


@finneyj commented on Mon Sep 21 2020

Yep - sounds like a good probe.


@dpgeorge commented on Thu Sep 24 2020

Example 1: simple wait, record, stop, play.

from microbit import sleep, microphone, audio

sample_buf = bytearray(16000)
record_rate = 8000  # will record max 2 seconds
play_rate = 10000  # play a bit faster to warp the voice a bit

while True:
    # wait until sound is detected (we may miss recording the first bit...)
    while microphone.current_sound() != microphone.LOUD:
        sleep(1)

    # record into the given buffer, in the background
    microphone.record(sample_buf, rate=record_rate, wait=False)

    # record at least 100ms of sound
    sleep(100)

    # wait until it's quiet (recording will stop if it runs out of buffer space)
    while microphone.current_sound() != microphone.QUIET:
        sleep(1)

    # stop recording if it's still ongoing, and get total number of samples recorded
    num_samples = microphone.stop()

    # play samples (in the foreground, ie blocking until it's all played)
    audio.play(sample_buf, rate=play_rate, samples=num_samples)

Example 2: recording via the audio object instead of microphone (to support an external mic?), and the record function has the ability to stop on a given event.

from microbit import sleep, microphone, audio

sample_buf = bytearray(16000)
record_rate = 8000  # will record max 2 seconds
play_rate = 10000  # play a bit faster to warp the voice a bit

while True:
    # wait until sound is detected (we may miss recording the first bit...)
    while microphone.current_sound() != microphone.LOUD:
        sleep(1)

    # record the sound until the given event, or the buffer is full
    num_samples = audio.record_until(sample_buf, microphone.QUIET, rate=record_rate)

    # play back the samples
    audio.play(sample_buf, rate=play_rate, samples=num_samples)

Example 3: attempt to keep some samples before the loud event so the first part of the recording is not cut off.

from microbit import sleep, microphone, audio

sample_buf = bytearray(16000)
record_rate = 8000  # will record max 2 seconds
play_rate = 10000  # play a bit faster to warp the voice a bit

while True:
    # start pre-recording into the buffer in a loop, in the background
    microphone.prerecord(sample_buf, rate=record_rate)

    # wait until sound is detected (while we are recording)
    while microphone.current_sound() != microphone.LOUD:
        sleep(1)

    # switch from pre-recording to normal recording, but keeping the first 100ms of samples
    microphone.record(keep=record_rate * 0.1)

    # record at least 100ms of extra sound
    sleep(100)

    # wait until it's quiet (recording will stop if it runs out of buffer space)
    while microphone.current_sound() != microphone.QUIET:
        sleep(1)

    # stop recording if it's still ongoing, and get total number of samples recorded
    num_samples = microphone.stop()

    # play samples (in the foreground, ie blocking until it's all played)
    audio.play(sample_buf, rate=play_rate, samples=num_samples)

@dpgeorge commented on Thu Sep 24 2020

Example 4: Removing the concept of sample rate and samples.

from microbit import sleep, microphone, audio

sample_buf = audio.RecordingBuffer(2.0)

while True:
    # wait until sound is detected
    while microphone.current_sound() != microphone.LOUD:
        sleep(1)

    # record into the given buffer, in the background, keeping 100ms of past recording
    microphone.record_into(sample_buf, past_recording=0.1, wait=False)

    # record at least 100ms of sound
    sleep(100)

    # wait until it's quiet (recording will stop if it runs out of buffer space)
    while microphone.current_sound() != microphone.QUIET:
        sleep(1)

    # stop recording if it's still ongoing, and zero out any remaining sample bytes
    microphone.stop()

    # play samples (in the foreground, ie blocking until it's all played)
    audio.play(sample_buf, rate_mult=1.2)

Example 5: allocating the recording buffer automatically.

from microbit import sleep, microphone, audio

while True:
    # wait until sound is detected
    while microphone.current_sound() != microphone.LOUD:
        sleep(1)

    # record into the given buffer, in the background, keeping 100ms of past recording
    sample_buf = microphone.record_for(2.0, past_recording=0.1)

    # wait until it's quiet before playing
    while microphone.current_sound() != microphone.QUIET:
        sleep(1)

    audio.apply_effect(sample_buf, audio.EchoEffect(delay=0.1, volume=0.8))

    # play samples (in the foreground, ie blocking until it's all played)
    audio.play(sample_buf, effect=audio.EchoEffect(delay=0.1, volume=0.8))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions