audioDeviceWriter
Play to sound card
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.
See Audio I/O: Buffering, Latency, and Throughput for a detailed explanation of the audio device writer data flow.
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
returns a
System object, deviceWriter
= audioDeviceWriterdeviceWriter
, that writes audio samples to an audio
output device in real time.
sets the SampleRate property to
deviceWriter
= audioDeviceWriter(sampleRateValue
)sampleRateValue
.
sets each property deviceWriter
= audioDeviceWriter(___,Name,Value
)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 the
release
function unlocks them.
If a property is tunable, you can change its value at any time.
For more information on changing property values, see System Design in MATLAB Using System Objects.
Driver
— Driver used to access audio device (Windows only)
'DirectSound'
(default) | 'ASIO'
| 'WASAPI'
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
If
Driver
is specified as'ASIO'
, useasiosettings
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
— Device used to play audio samples
default audio device (default) | character vector | string scalar
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
SampleRate
— Sample rate of signal sent to audio device (Hz)
44100
(default) | positive integer
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
BitDepth
— Data type used by the device
'16-bit integer'
(default) | '8-bit integer'
| '24-bit integer'
| '32-bit float'
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
SupportVariableSizeInput
— Support variable frame size
false
(default) | true
Option to support variable frame size, specified as true
or
false
.
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
BufferSize
— Buffer size of audio device
4096
(default) | positive integer
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 the
BufferSize
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
ChannelMappingSource
— Source of mapping between input matrix and device channels
'Auto'
(default) | 'Property'
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
ChannelMapping
— Nondefault mapping between input matrix and device channels
[1:MaximumOutputChannels]
(default) | scalar | vector
Nondefault mapping between columns of input matrix and channels of output device, specified as a scalar or vector of valid channel indices. See the Specify Channel Mapping for audioDeviceWriter example for more information.
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
Description
writes one frame of audio samples, numUnderrun
= deviceWriter(audioToDevice
)audioToDevice
, to the selected
audio device and returns the number of audio samples underrun since the last call to
deviceWriter
.
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 your
audioDeviceWriter
System object.
Input Arguments
audioToDevice
— Audio to device
matrix
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
numUnderrun
— Number of samples underrun
scalar
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:
release(obj)
Specific to audioDeviceWriter
getAudioDevices | List available audio devices |
info | Get audio device information |
Common to All System Objects
Examples
Read from File and Write to Audio Device
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/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/toolbox/dsp/dsp/samples/speech_dft.mp3'
CompressionMethod: 'MP3'
NumChannels: 1
SampleRate: 22050
TotalSamples: 112320
Duration: 5.0939
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.
info(deviceWriter)
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)
Reduce Latency due to Output Device Buffer
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
bufferLatency = 0.0464
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
bufferLatency = 0.0116
Determine and Decrease Underrun
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.
Specify Channel Mapping for audioDeviceWriter
Specify nondefault channel mapping for an audioDeviceWriter
object. This example is hardware specific. It assumes that your computer has a default audio output device with two available channels.
Create an audioDeviceWriter
object with default settings.
deviceWriter = audioDeviceWriter;
By default, the audioDeviceWriter
object writes the maximum number of channels available, corresponding to the columns of the input matrix. Use info
to get the maximum number of channels of your device.
info(deviceWriter)
ans = struct with fields:
Driver: 'DirectSound'
DeviceName: 'Primary Sound Driver'
MaximumOutputChannels: 2
If deviceWriter
is called with one column of data, two channels are written to your audio output device. Both channels correspond to the one column of data.
Use the audioOscillator
object to output a tone to your audioDeviceWriter
object. Your object, sineGenerator
, returns a vector when called.
sineGenerator = audioOscillator;
Write the sine tone to your audio device. If you are using headphones, you can hear the tone from both channels.
count = 0; while count < 500 sine = sineGenerator(); deviceWriter(sine); count = count + 1; end
If your audioDeviceWriter
object is called with two columns of data, two channels are written to your audio output device. The first column corresponds to channel 1 of your audio output device, and the second column corresponds to channel 2 of your audio output device.
Write a two-column matrix to your audio output device. Column 1 corresponds to the sine tone, and column 2 corresponds to a static signal. If you are using headphones, you can hear the tone from one speaker and the static from the other speaker.
count = 0; while count < 500 sine = sineGenerator(); static = randn(length(sine),1); deviceWriter([sine,static]); count = count + 1; end
Specify alternative mappings between channels of your device and columns of the output matrix by indicating the output channel number at an index corresponding to the input column. Set ChannelMappingSource
to 'Property'
. Indicate that the first column of your input data writes to channel 2 of your output device, and that the second column of your input data writes to channel 1 of your output device. To modify the channel mapping, you must first unlock the audioDeviceReader
object.
release(deviceWriter)
deviceWriter.ChannelMappingSource = 'Property';
deviceWriter.ChannelMapping = [2,1];
Play your audio signals with reversed mapping. If you are using headphones, notice that the tone and static have switched speakers.
count = 0; while count < 500 sine = sineGenerator(); static = randn(length(sine),1); deviceWriter([sine,static]); count = count + 1; end
Extended Capabilities
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
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 Run Audio I/O Features Outside MATLAB and Simulink.
Version History
Introduced in R2016aR2023b: Play mono signal on only one channel of a stereo device
Specify a channel mapping in the audioDeviceWriter
object to play a mono
signal on only one channel of a stereo device. Set the
ChannelMappingSource
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.
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)