audioDeviceWriter - Play to sound card - MATLAB (original) (raw)
Description
The audioDeviceWriter
System object™ writes audio samples to an audio output device. Properties of the audio device writer specify the driver, the device, and device attributes such as sample rate, bit depth, and buffer size.
Data Flow of Audio Device Writer
- Call the object to input an audio signal frame to the
audioDeviceWriter
. - The
audioDeviceWriter
uses the specified driver to pass the frame (device input) to the buffer of your specified audio device. - The audio device performs digital-to-analog conversion at the specified sample rate and bit depth.
- The audio device outputs an analog chunk to your speaker.
To stream data to an audio device:
- Create the
audioDeviceWriter
object and set its properties. - Call the object with arguments, as if it were a function.
To learn more about how System objects work, see What Are System Objects?
Creation
Syntax
Description
`deviceWriter` = audioDeviceWriter
returns a System object, deviceWriter
, that writes audio samples to an audio output device in real time.
`deviceWriter` = audioDeviceWriter(`sampleRateValue`)
sets the SampleRate property tosampleRateValue
.
`deviceWriter` = audioDeviceWriter(___,`Name,Value`)
sets each property Name
to the specified Value
. Unspecified properties have default values.
Example: deviceWriter = audioDeviceWriter(48000,'BitDepth','8-bit integer')
creates a System object, deviceWriter
, that operates at a 48 kHz sample rate and an 8-bit integer bit depth.
Properties
Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and therelease function unlocks them.
If a property is tunable, you can change its value at any time.
For more information on changing property values, seeSystem Design in MATLAB Using System Objects.
Driver used to access your audio device, specified as'DirectSound'
, 'ASIO'
, or'WASAPI'
.
- ASIO™ drivers do not come pre-installed on Windows® machines. To use the
'ASIO'
driver option, install an ASIO driver outside of MATLAB®.
Note
IfDriver
is specified as'ASIO'
, use asiosettings (Audio Toolbox) to set the sound card buffer size to the buffer size of youraudioDeviceWriter
System object. - WASAPI drivers are supported for exclusive-mode only.
ASIO and WASAPI drivers do not provide sample rate conversion. For ASIO and WASAPI drivers, set SampleRate
to a sample rate supported by your audio device.
This property applies only on Windows machines. Linux® machines always use the ALSA driver. Mac machines always use the CoreAudio driver.
To specify nondefault Driver
values, you must have an Audio Toolbox™ license.
Data Types: char
| string
Device used to play audio samples, specified as a character vector or string scalar. Use getAudioDevices
to list available devices for the selected driver.
Data Types: char
| string
Sample rate of signal sent to audio device, in Hz, specified as a positive integer. The range of SampleRate
depends on your audio hardware.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
Data type used by the device, specified as a character vector or string scalar. Before performing digital-to-analog conversion, the input data is cast to a data type specified by BitDepth
.
To specify a nondefault BitDepth
, you must have an Audio Toolbox license.
Data Types: char
| string
Option to support variable frame size, specified as true
orfalse
.
false
–– If theaudioDeviceWriter
object is locked, the input must have the same frame size at each call. The buffer size of your audio device is the same as the input frame size.true
–– If theaudioDeviceWriter
object is locked, the input frame size can change at each call. The buffer size of your audio device is specified through the BufferSize property.
Data Types: char
Buffer size of audio device, specified as a positive integer.
Note
If Driver
is specified as 'ASIO'
, open the ASIO UI to set the sound card buffer size to theBufferSize
value of your audioDeviceWriter
System object.
Dependencies
To enable this property, set SupportVariableSizeInput to true
.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
Source of mapping between columns of input matrix and channels of audio output device, specified as 'Auto'
or 'Property'
.
'Auto'
–– Default settings determine the mapping between columns of input matrix and channels of audio output device. For example, suppose that your input is a matrix with four columns, and your audio device has four channels available. Column 1 of your input data writes to channel 1 of your device, column 2 of your input data writes to channel 2 of your device, and so on.'Property'
–– The ChannelMapping property determines the mapping between columns of input matrix and channels of audio output device.
Data Types: char
| string
Nondefault mapping between columns of input matrix and channels of output device, specified as a scalar or vector of valid channel indices.
To selectively map between columns of the input matrix and your sound card's output channels, you must have an Audio Toolbox license.
Dependencies
To enable this property, set ChannelMappingSource to 'Property'
.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
Usage
Syntax
Description
[numUnderrun](audiodevicewriter-system-object.html#mw%5F7285c403-2b0b-4747-b542-e2047beff574)= deviceWriter([audioToDevice](audiodevicewriter-system-object.html#mw%5Fde214585-205f-44e4-b3aa-88b50a0ae85a))
writes one frame of audio samples, audioToDevice
, to the selected audio device and returns the number of audio samples underrun since the last call todeviceWriter
.
Note: When you call the audioDeviceWriter
System object, the audio device specified by the Device
property is locked. An audio device can be locked by only one audioDeviceWriter
at a time. To release the audio device, call release
on youraudioDeviceWriter
System object.
Input Arguments
Audio signal to write to device, specified as a matrix. The columns of the matrix are treated as independent audio channels.
If audioToDevice
is of data type 'double'
or 'single'
, the audio device writer clips values outside the range [–1, 1]. For other data types, the allowed input range is [min, max] of the specified data type.
Data Types: single
| double
| int16
| int32
| uint8
Output Arguments
Number of samples by which the audio device writer queue was underrun since the last call to deviceWriter
.
Data Types: uint32
Object Functions
To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named obj
, use this syntax:
getAudioDevices | List available audio devices |
---|---|
info | Characteristic information about audio device writer |
clone | Create duplicate System object |
---|---|
isLocked | Determine if System object is in use |
release | Release resources and allow changes to System object property values and input characteristics |
reset | Reset internal states of System object |
step | Run System object algorithm |
setup | One-time set up tasks for System objects |
Examples
Read an MP3 audio file and play it through your default audio output device.
Create a dsp.AudioFileReader
object with default settings. Use the audioinfo
function to return a structure containing information about the audio file.
fileReader = dsp.AudioFileReader('speech_dft.mp3'); fileInfo = audioinfo('speech_dft.mp3')
fileInfo = struct with fields: Filename: '/mathworks/devel/bat/filer/batfs2566-0/Bdoc25a.2864802/build/runnable/matlab/toolbox/dsp/dsp/samples/speech_dft.mp3' CompressionMethod: 'MP3' NumChannels: 1 SampleRate: 22050 TotalSamples: 110033 Duration: 4.9902 Title: [] Comment: [] Artist: [] BitRate: 64
Create an audioDeviceWriter
object and specify the sample rate.
deviceWriter = audioDeviceWriter('SampleRate',fileInfo.SampleRate);
Call setup
to reduce the computational load of initialization in an audio stream loop.
setup(deviceWriter,zeros(fileReader.SamplesPerFrame,... fileInfo.NumChannels))
Use the info
function to obtain the characteristic information about the device writer.
ans = struct with fields: Driver: 'ALSA' DeviceName: 'ALSAdefault' MaximumOutputChannels: 32
In an audio stream loop, read an audio signal frame from the file, and write the frame to your device.
while ~isDone(fileReader) audioData = fileReader(); deviceWriter(audioData); end
Close the input file and release the device.
release(fileReader) release(deviceWriter)
Latency due to the output device buffer is the time delay of writing one frame of data. Modify default properties of your audioDeviceWriter
System object™ to reduce latency due to device buffer size.
Create a dsp.AudioFileReader
System object to read an audio file with default settings.
fileReader = dsp.AudioFileReader('speech_dft.mp3');
Create an audioDeviceWriter
System object and specify the sample rate to match that of the audio file reader.
deviceWriter = audioDeviceWriter(... 'SampleRate',fileReader.SampleRate);
Calculate the latency due to your device buffer, in seconds.
bufferLatency = fileReader.SamplesPerFrame/deviceWriter.SampleRate %#ok
Set the SamplesPerFrame
property of your dsp.AudioFileReader
System object to 256. Calculate the buffer latency in seconds.
fileReader.SamplesPerFrame = 256; bufferLatency = fileReader.SamplesPerFrame/deviceWriter.SampleRate
Underrun refers to output signal silence, which occurs when the audio stream loop does not keep pace with the output device. Determine the underrun of an audio stream loop, add artificial computational load to the audio stream loop, and then modify properties of your audioDeviceWriter
object to decrease underrun. Your results depend on your computer.
Create a dsp.AudioFileReader
object, and specify the file to read. Use the audioinfo
function to return a structure containing information about the audio file.
fileReader = dsp.AudioFileReader('speech_dft.mp3'); fileInfo = audioinfo('speech_dft.mp3');
Create an audioDeviceWriter
object. Use the SampleRate
of the file reader as the SampleRate
of the device writer. Call setup
to reduce the computational load of initialization in an audio stream loop.
deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate); setup(deviceWriter,zeros(fileReader.SamplesPerFrame,... fileInfo.NumChannels))
Run your audio stream loop with input from file and output to device. Print the total samples underrun and the underrun in seconds.
totalUnderrun = 0; while ~isDone(fileReader) input = fileReader(); numUnderrun = deviceWriter(input); totalUnderrun = totalUnderrun + numUnderrun; end fprintf('Total samples underrun: %d.\n',totalUnderrun)
Total samples underrun: 0.
fprintf('Total seconds underrun: %d.\n',double(totalUnderrun)/double(deviceWriter.SampleRate))
Total seconds underrun: 0.
Release your dsp.AudioFileReader
and audioDeviceWriter
objects and set your counter variable to zero.
release(fileReader) release(deviceWriter) totalUnderrun = 0;
Use pause
to mimic an algorithm that takes 0.075 seconds to process. The pause causes the audio stream loop to go slower than the device, which results in periods of silence in the output audio signal.
while ~isDone(fileReader) input = fileReader(); numUnderrun = deviceWriter(input); totalUnderrun = totalUnderrun + numUnderrun; pause(0.075) end fprintf('Total samples underrun: %d.\n',totalUnderrun)
Total samples underrun: 68608.
fprintf('Total seconds underrun: %d.\n',double(totalUnderrun)/double(deviceWriter.SampleRate))
Total seconds underrun: 3.111474e+00.
Release your audioDeviceReader
and dsp.AudioFileWriter
and set the counter variable to zero.
release(fileReader) release(deviceWriter) totalUnderrun = 0;
Set the frame size of your audio stream loop to 2048. Because the SupportVariableSizeInput
property of your audioDeviceWriter
System object is set to false
, the buffer size of your audio device is the same size as the input frame size. Increasing your device buffer size decreases underrun.
fileReader = dsp.AudioFileReader('speech_dft.mp3'); fileReader.SamplesPerFrame = 2048; fileInfo = audioinfo('speech_dft.mp3');
deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate); setup(deviceWriter,zeros(fileReader.SamplesPerFrame,fileInfo.NumChannels))
Calculate the total underrun.
while ~isDone(fileReader) input = fileReader(); numUnderrun = deviceWriter(input); totalUnderrun = totalUnderrun + numUnderrun; pause(0.075) end fprintf('Total samples underrun: %d.\n',totalUnderrun)
Total samples underrun: 0.
fprintf('Total seconds underrun: %d.\n',double(totalUnderrun)/double(deviceWriter.SampleRate))
Total seconds underrun: 0.
The increased frame size reduces the total underrun of your audio stream loop. However, increasing the frame size also increases latency. Other approaches to reduce underrun include:
- Increasing the buffer size independent of input frame size. To increase buffer size independent of input frame size, you must first set
SupportVariableSizeInput
totrue
. This approach also increases latency. - Decreasing the sample rate. Decreasing the sample rate reduces both latency and underrun at the cost of signal resolution.
- Choosing an optimal driver and device for your system.
Extended Capabilities
Usage notes and limitations:
- System Objects in MATLAB Code Generation (MATLAB Coder)
- The executable generated from this System object relies on prebuilt dynamic library files (
.dll
files) included with MATLAB. Use thepackNGo
function to package the code generated from this object and all the relevant files in a compressed zip file. Using this zip file, you can relocate, unpack, and rebuild your project in another development environment where MATLAB is not installed. For more details, see How To Run a Generated Executable Outside MATLAB.
Version History
Introduced in R2016a
Specify a channel mapping in the audioDeviceWriter
object to play a mono signal on only one channel of a stereo device. Set theChannelMappingSource
property to "Property"
and set the ChannelMapping
property to 1 (left) or 2 (right).
This change affects only DirectSound and CoreAudio drivers.
Previously, setting ChannelMapping
to 1 would play a mono signal in both left and right stereo channels. The default behavior for the object remains the same.