LinuxDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


An Introduction to Linux Audio
Pages: 1, 2, 3, 4

Python: PyAudio and PyGst with Gstreamer

Even higher level than JACK is the idea of using the Python bindings for Gstreamer, or the PyAudio bindings for PortAudio, a cross-platform audio library.



Here is an example from the PyAudio docs. We import the audio libraries first and then sys which enables us to read and write files. Then we do what we've done in every example, which is to set the format of the audio and the audio device. We open a stream, grab the stuff, and then save it.

""" Record a few seconds of audio and save to a WAVE file. """
import pyaudio
import wave
import sys

chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()

stream = p.open(format = FORMAT,
                channels = CHANNELS,
                rate = RATE,
                input = True,
                frames_per_buffer = chunk)

print "* recording"
all = []
for i in range(0, RATE / chunk * RECORD_SECONDS):
    data = stream.read(chunk)
    all.append(data)
print "* done recording"

stream.close()
p.terminate()

# write data to WAVE file
data = ''.join(all)
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(data)
wf.close()

Note how minimal this code is. There is no GUI, of course, so that helps as well.

A good introduction to Gstreamer is Jono Bacon's article that describes the workings of Gstreamer and the PyGst bindings. Gstreamer offers quite a lot of creative possibilities and, unlike ESD, offers the possibility of having more than one audio stream playing at one time, amongst many other features.

Below is an example of code from the PyGst docs of a simple audio player. We grab the sys, windowing, and pygst stuff, set up the window and the player, and away we go. Note that some implementations, particularly for small devices, are missing crucial bits. For example, I was interested to do a command line version for a Nokia 770 to play loops and wasn't able to.

#!/usr/bin/env python

import sys, os, os.path
import pygtk, gtk, gobject
import pygst
pygst.require("0.10")
import gst

class GTK_Main:
        
        def __init__(self):
             window = gtk.Window(gtk.WINDOW_TOPLEVEL)
             window.set_title("Audio-Player")
             window.set_default_size(400, 300)
             window.connect("destroy", gtk.main_quit, "WM destroy")
             vbox = gtk.VBox()
             window.add(vbox)
             self.entry = gtk.Entry()
             vbox.pack_start(self.entry, False, True)
             self.button = gtk.Button("Start")
             self.button.connect("clicked", self.start_stop)
             vbox.add(self.button)
             window.show_all()
                
             self.player = gst.element_factory_make("playbin", "player")
             fakesink = gst.element_factory_make('fakesink', "my-fakesink")
             self.player.set_property("video-sink", fakesink)
             bus = self.player.get_bus()
             bus.add_signal_watch()
             bus.connect('message', self.on_message)
                
        def start_stop(self, w):
             if self.button.get_label() == "Start":
                   filepath = self.entry.get_text()
                   if os.path.exists(filepath):
                         self.button.set_label("Stop")
                         self.player.set_property('uri', "file://" + filepath)
                                self.player.set_state(gst.STATE_PLAYING)
             else:
                   self.player.set_state(gst.STATE_NULL)
                   self.button.set_label("Start")
                                                
        def on_message(self, bus, message):
             t = message.type
             if t == gst.MESSAGE_EOS:
                   self.player.set_state(gst.STATE_NULL)
                   self.button.set_label("Start")
             elif t == gst.MESSAGE_ERROR:
                   self.player.set_state(gst.STATE_NULL)
                   self.button.set_label("Start")

gtk.gdk.threads_init()
GTK_Main()
gtk.main()

Here we actually have a GUI, but you can see the amount of code needed is still relatively small compared to what would be required with some lower-level language.

Conclusion

Which way you might go to get into Linux Audio depends on what you'd like to achieve. If you're planning to just have some fun while learning something, then wherever you start will be OK. If the fun leads to ideas, then you'll soon figure out whether you need to be deeper into the machine or whether you just need to be sketching on the surface. Just bear in mind that the higher the level you're on, the more you're bound by what other people think about how things should be. This is mostly good in terms of ease and implementation time, but could be bad in terms of constricted horizons.

A good mailing list to join if you get serious is the Linux Audio Dev list, which describes itself like this: "The Linux Audio Developers (LAD) list is dedicated to sound architecture and application development for the Linux Operating System. With its proven stability and scalability, it is a perfect foundation for the handling and processing of large amounts of audio data. Our goal is to encourage widespread code re-use and cooperation, and to provide a common forum for all audio related software projects and an exchange point for a number of other special-interest mailing lists."

The archives of this list can also be useful for answering questions, as can using the likes of krugle.com or Google's Codesearch.

At this point, you might say to yourself, well, actually, what I really want to do is make noises or non-standard kinds of music. In that case you could have a look at Csound or Pure Data. You could also look into the synthesis and DSP side of programming, which is something we haven't looked at in this article.

John Littler is chief gopher for Mstation.org.


Return to LinuxDevCenter.com.


Linux Online Certification

Linux/Unix System Administration Certificate Series
Linux/Unix System Administration Certificate Series — This course series targets both beginning and intermediate Linux/Unix users who want to acquire advanced system administration skills, and to back those skills up with a Certificate from the University of Illinois Office of Continuing Education.

Enroll today!


Linux Resources
  • Linux Online
  • The Linux FAQ
  • linux.java.net
  • Linux Kernel Archives
  • Kernel Traffic
  • DistroWatch.com


  • Sponsored by: