Rotbaard
Rotbaard

Reputation: 1

Kivy/Audiostream microphone input data format

I am playing around with some basics of the Audiostream package for Kivy.

I would like to make a simple online input-filter-output system, for example, take in microphone data, impose a band-pass filter, send to speakers.

However, I can't seem to figure out what data format the microphone input is in or how to manipulate it. In code below, buf is type string, but how can I get the data out of it to manipulate it in such a way [i.e. function(buf)] to do something like a band-pass filter?

The code currently functions to just send the microphone input directly to the speakers.

Thanks.

from time import sleep
from audiostream import get_input
from audiostream import get_output, AudioSample

#get speakers, create sample and bind to speakers
stream = get_output(channels=2, rate=22050, buffersize=1024)
sample = AudioSample()
stream.add_sample(sample)


#define what happens on mic input with arg as buffer
def mic_callback(buf):
    print 'got', len(buf)
    #HERE: How do I manipulate buf?
    #modified_buf = function(buf)
    #sample.write(modified_buf)
    sample.write(buf)


# get the default audio input (mic on most cases)
mic = get_input(callback=mic_callback)
mic.start()
sample.play()
sleep(3)  #record for 3 seconds
mic.stop()
sample.stop()

Upvotes: 0

Views: 933

Answers (1)

tito
tito

Reputation: 13261

The buffer is composed of bytes that need to be interpreted as signed short. You can use struct or array module to get value. In your example, you have 2 channels (L/R). Let's say you wanna to have the right channel volume down by 20% (aka 80% of the original sound only for right channel)

from array import array

def mic_callback(buf):
    # convert our byte buffer into signed short array
    values = array("h", buf)

    # get right values only
    r_values = values[1::2]

    # reduce by 20%
    r_values = map(lambda x: x * 0.8, r_values)

    # you can assign only array for slice, not list
    # so we need to convert back list to array
    values[1::2] = array("h", r_values)

    # convert back the array to a byte buffer for speaker
    sample.write(values.tostring())

Upvotes: 1

Related Questions