Audio Track Example

This example shows how to play a sound using the Android media APIs.

A screenshot of the application.

We import the classes and modules needed by our application. The most relevant classes are those from the android.media module.

from java.lang import Math
from java.nio import ByteBuffer
from android.app import Activity
from android.media import AudioFormat, AudioManager, AudioTrack
from android.os import Bundle
from android.view import View
from android.widget import Button, LinearLayout

The AudioTrackActivity class is derived from the standard Activity class and represents the application. Android will create an instance of this class when the user runs it.

class AudioTrackActivity(Activity):

    __interfaces__ = [View.OnClickListener]

The class implements the View.OnClickListener interface, declaring this in the list of interfaces defined by the __interfaces__ attribute. Implementing this interface involves implementing the onClick method shown below.

The initialisation method simply calls the corresponding method in the base class.

    def __init__(self):
    
        Activity.__init__(self)

The onCreate method calls the corresponding method in the base class to help set up the activity, and we set up the user interface.

    @args(void, [Bundle])
    def onCreate(self, bundle):
    
        Activity.onCreate(self, bundle)

We create a button with a "Play sound" label and register the activity as its listener for click callbacks.

        button = Button(self)
        button.setText("Play sound")
        button.setOnClickListener(self)

The button is placed in a vertical layout which is used as the main content in the activity.

        layout = LinearLayout(self)
        layout.setOrientation(layout.VERTICAL)
        layout.addView(button)
        
        self.setContentView(layout)

The onClick method is called whenever the button defined above is clicked. If the activity was registered as a listener with other buttons then we would distinguish between them using the View object passed to this method.

Instead of playing a pre-made sound, we create a waveform using the standard Java buffer API and a loop to fill a ByteBuffer with samples.

    @args(void, [View])
    def onClick(self, view):
    
        sample_rate = 22050
        f = 1046.5
        l = 1.5
        samples = int(sample_rate * l)
        df = f/samples
        
        buf = ByteBuffer.allocate(samples)
        i = 0
        while i < samples:
            p = 2 * Math.PI * f * i / sample_rate
            b = int(127 + (64.0 * Math.sin(p)))
            # Write the byte to the buffer without updating the position.
            buf.put(i, byte(b))
            f += df
            i += 1

We create an AudioTrack instance, passing information about the sample data to ensure that it will be played correctly.

        track = AudioTrack(AudioManager.STREAM_MUSIC, sample_rate,
            AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_8BIT,
            samples, AudioTrack.MODE_STATIC)

Finally, we add the sample buffer to the track and play it.

        track.write(buf.array(), 0, samples)
        track.play()

Files