/* audio.q: a simple portable audio interface 05-13-03 AG */ /* This file is part of the Q programming system. The Q programming system is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. The Q programming system is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This module implements a (near-)realtime audio interface on top of Phil Burk's PortAudio library V1.8 (http://www.portaudio.com/). */ import clib; /* Manifest constants. These are used for the INFO and MODE parameters of the open_audio_stream function. */ public var const // sample formats PA_FLOAT32, PA_INT16, PA_INT32, PA_INT24, PA_PACKED_INT24, PA_INT8, PA_UINT8, PA_CUSTOM_FORMAT, // modes PA_READ, PA_WRITE, PA_RDWR; /* Default input and output devices. */ public var AUDIO_IN, AUDIO_OUT; private extern audio_vars; def (PA_FLOAT32, PA_INT16, PA_INT32, PA_INT24, PA_PACKED_INT24, PA_INT8, PA_UINT8, PA_CUSTOM_FORMAT, PA_READ, PA_WRITE, PA_RDWR, AUDIO_IN, AUDIO_OUT) = audio_vars; /* Device info. The audio_devices function returns information about the available audio devices as a list of quintuples of the form (NAME, INPUT_CHANNELS, OUTPUT_CHANNELS, SAMPLE_RATES, NATIVE_FORMATS) indicating, respectively, the device name, maximum number of input and output channels, the available sample rates (either a list, or a pair indicating a continuous range) and the native sample formats of the device (bitwise `or' of all supported formats). */ public extern audio_devices; /* Minimum number of buffers and latency. For a given buffer size SIZE (number of frames) and sampling rate RATE, the min_buffers function returns the minimum number NUM of buffers required by PortAudio for proper operation. The latency function determines the I/O latency in milliseconds for the given total buffer size (i.e., NUM*SIZE) and frame rate RATE. */ /* Note that on most systems PortAudio chooses fairly conservative values to prevent audio glitches. You can change the minimum latency required by PortAudio by setting the PA_MIN_LATENCY_MSEC environment variable accordingly. */ public extern min_buffers SIZE RATE; public latency SIZE RATE; latency SIZE RATE = 1000*SIZE/RATE; /* Audio stream objects. These are returned by the open_audio_stream function and used by the other functions. */ public extern type AudioStream; public is_audio_stream X; is_audio_stream _:AudioStream = true; is_audio_stream _ = false otherwise; /* Open and close an audio stream. When opening an audio stream you have to specify the index ID of the device in the device table, the mode of the stream (PA_READ for read-only, PA_WRITE for write-only, or PA_RDWR for read/write access) and the description INFO (a quintuple (SAMPLE_RATE, CHANNELS, FORMAT, SIZE, NUM) denoting the desired sample rate, number of channels, sample format, buffer size and number of buffers, respectively). The buffer size denotes the number of frames to be processed at a time. The number of buffers is optional; if it is omitted or zero then the minimum will be assumed. These parameters might need some tuning in order to prevent drop-outs while achieving an acceptable latency. Also note that not all sample formats are supported on all platforms, but PA_FLOAT32, PA_INT16 and PA_INT32 should always work. Audio streams (and the associated devices) are closed automatically when the corresponding AudioStream object is garbage-collected. They can also be closed explicitly with the close_audio_stream function. */ public extern open_audio_stream ID MODE INFO; public extern close_audio_stream AS; /* Retrieve information about an audio stream. The audio_stream_id function returns the device index, audio_stream_info the description of the stream (sample rate, channels, etc.). The audio_stream_time function yields the current time of the stream (starting from some arbitrary value) as a floating point value, which is useful for synchronization purposes. The bytes_per_sample and bytes_per_frame functions return the number of bytes per sample and frame for the chosen format and number of channels, which is useful for decoding the data. */ public extern audio_stream_id AS, audio_stream_info AS; public extern audio_stream_time AS; public extern bytes_per_sample AS, bytes_per_frame AS; /* Read and write an audio stream. Audio data is encoded as a raw byte string which contains a sequence of frames (interleaving samples for multichannel streams) in the stream's format. For the read function, NFRAMES determines the number of frames to be read. For the write function, only complete frames will be written, i.e., any extra bytes at the end of the byte string are ignored. Whatever the buffer size of the stream may be, you can read or write an arbitrary number of samples in a single operation; if the request cannot be satisfied immediately, the functions will block, i.e., the calling thread will be suspended until the given number of frames has been read or written. */ public extern read_audio_stream AS NFRAMES; public extern write_audio_stream AS DATA; /* Determine how much audio data (number of frames) could be read or written without blocking. */ public extern audio_stream_readable AS; public extern audio_stream_writeable AS;