0

I was just playing around with sound input and output on a raspberry pi using python. My plan was to read the input of a microphone, manipulate it and playback the manipulated audio. At the moment I tried to read and playback the audio. The reading seems to work, since i wrote the read data into a wave file in the last step, and the wave file seemed fine. But the playback is noise sounds only. Playing the wave file worked as well, so the headset is fine. I think maybe I got some problem in my settings or the output format. The code:

import alsaaudio as audio
import time
import audioop


#Input & Output Settings
periodsize = 1024
audioformat = audio.PCM_FORMAT_FLOAT_LE
channels = 16
framerate=8000

#Input Device
inp = audio.PCM(audio.PCM_CAPTURE,audio.PCM_NONBLOCK,device='hw:1,0')
inp.setchannels(channels)
inp.setrate(framerate)
inp.setformat(audioformat)
inp.setperiodsize(periodsize)

#Output Device
out = audio.PCM(audio.PCM_PLAYBACK,device='hw:0,0')
out.setchannels(channels)
out.setrate(framerate)
out.setformat(audioformat)
out.setperiodsize(periodsize)


#Reading the Input
allData = bytearray()
count = 0
while True:
    #reading the input into one long bytearray
    l,data = inp.read()
    for b in data:
        allData.append(b)

    #Just an ending condition
    count += 1
    if count == 4000:
        break

    time.sleep(.001)


#splitting the bytearray into period sized chunks
list1 = [allData[i:i+periodsize] for i in range(0, len(allData), periodsize)]

#Writing the output
for arr in list1:
    # I tested writing the arr's to a wave file at this point
    # and the wave file was fine
    out.write(arr)

Edit: Maybe I should mention, that I am using python 3

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
Mein Name
  • 527
  • 3
  • 14
  • It should not be necessary to open 16 channels. Does the behavior change, if you set `channel = 1`? – nucleon May 21 '17 at 09:31
  • Just tried it with 1 Channel, unluckily it is still the same. Maybe I should mention, that I am using python 3 (will edit the question) – Mein Name May 21 '17 at 17:17
  • 1
    You could check the supported device parameters with aplay/arecord --dump-hw-params and try to play back a wave file directly from console using aplay. – nucleon May 21 '17 at 17:20

2 Answers2

0

I just found the answer. audioformat = audio.PCM_FORMAT_FLOAT_LE this format isn't the one used by my Headset (just copied and pasted it without a second thought). I found out about my microphones format (and additional information) by running speaker-test in the console.

Since my speakers format is S16_LE the code works fine with audioformat = audio.PCM_FORMAT_S16_LE

Mein Name
  • 527
  • 3
  • 14
0

consider using plughw (alsa subsystem supporting resampling/conversion) for the sink part of the chain at least:

#Output Device out = audio.PCM(audio.PCM_PLAYBACK,device='plughw:0,0')

this should help to negotiate sampling rate as well as the data format.

periodsize is better to estimate based on 1/times of the sample rate like:

periodsize = framerate / 8 (8 = times for 8000 KHz sampling rate)

and sleeptime is better to estimate as a half of the time necessary to play periodsize:

sleeptime = 1.0 / 16 (1.0 - is a second, 16 = 2*times for 8000 KHz sampling rate)

Oleg Kokorin
  • 2,288
  • 2
  • 16
  • 28