LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   python alsa: How to play smoothly? (http://www.linuxquestions.org/questions/programming-9/python-alsa-how-to-play-smoothly-770283/)

eantoranz 11-19-2009 02:03 PM

python alsa: How to play smoothly?
 
Hi!

I'm working on a personal research project. What I need to do is to be able to play waves at will.

I tried this morning to use alsa to have the output straight into the speakers but I just can't get to play waves smoothly without sound breakage.

I tried with different PCM modes but none worked. I also tried with PCM_NORMAL using a separate thread to not block my wave calculations, but that didn't work either.

So, to keep it simple, take a look at this two versions of the same file:

Simple:
http://bazaar.launchpad.net/~eantora.../WavePlayer.py
With threads:
http://bazaar.launchpad.net/~eantora.../WavePlayer.py

You will need the Wave.py from the project too.
http://bazaar.launchpad.net/~eantora...46/bin/Wave.py

The way to call it is very simple:

./WavePlayer.py 440

That should play a simple A4 sine wave on both channels.

Thanks for any help you could provide.

ntubski 11-21-2009 01:13 PM

I got only silence from your program. :confused:

Just looking at the code it seems that you call math.sin a whole lot which is unnecessary: just calculate one period and then repeat it.

The following works for me without any breakage, though I use 8-bit samples because I didn't feel like bit-bashing.
Code:

#!/usr/bin/env python

import alsaaudio, sys

from numpy import arange        # like range, but supports floating point
from math import pi, sin

channels = 2
sample_size = 1                    # bytes per sample
frame_size = channels * sample_size # bytes per frame
frame_rate = 44100                  # frames per second
byte_rate = frame_rate * frame_size # bytes per second
# 1 second worth of data per pcm.write() call
# decrease if shorter notes are needed
period_size = frame_rate

pcm = alsaaudio.PCM(alsaaudio.PCM_PLAYBACK)
pcm.setchannels(channels)
pcm.setformat(alsaaudio.PCM_FORMAT_U8)
def quantize(f):                # map (-1..1) -> [0..256)
    return int((f+1)*127)      # depends on PCM format
pcm.setrate(frame_rate)
pcm.setperiodsize(period_size)

def sine_wave(freq):
    wave = [chr(quantize(sin(x))) * channels for x
            in arange(0, 2*pi, 2*pi / (frame_rate / freq))]
    wave_data = "".join(wave)
    (nwaves, extra_bytes) = divmod(period_size * frame_size, len(wave_data))
    pcm.write((wave_data * nwaves) + wave_data[:extra_bytes])

for i in range(10):
    sine_wave(220)
    sine_wave(440)



All times are GMT -5. The time now is 11:44 AM.