Generate Multichannel Audio
R2026bThis example shows how to generate audio signals on multiple output channels using a multichannel audio device. In the example, you play segments of Handel's "Hallelujah Chorus" through different speaker combinations to create listening effects.
Specifically, you first create the effect of sound moving around the room by playing each segment on a single speaker paired with the sub-woofer. You then create the effect of a growing choir by playing each segment on progressively larger groups of speakers. This example uses a 5.1 surround-sound audio device that supports six output channels. Use daqlist("directsound") to identify available audio devices on your system. If your device supports only two output channels, see the Stereo Alternative section in this example.
Load Audio Data
Load Handel's "Hallelujah". The handel MAT-file contains the audio waveform y and the sampling frequency Fs.
load handel;
Create Data Acquisition Object
Create a DataAcquisition object, using directsound as the vendor ID.
dq = daq("directsound");
Add Output Channels
Add six audio output channels to the DataAcquisition object, using the addoutput function. Replace "Audio7" with the device ID of your multichannel audio device. You can get the device ID from the daqlist output.
deviceID = "Audio7"; numChannels = 6; addoutput(dq,deviceID,1:numChannels,"Audio");
Set the generation scan rate to match the audio sampling frequency.
dq.Rate = Fs;
Plot Audio Data
To view the segments corresponding to each "Hallelujah" in the chorus, plot the audio waveform.
figure; t = (0:length(y)-1) / Fs; plot(t,y,"k"); xlabel("Time (s)"); ylabel("Amplitude"); title("Original Song with Noisy Envelope vs Time");

Define Segment Boundaries
Divide the audio into five contiguous segments at the approximate sample indices where each "Hallelujah" ends.
segmentEnd = [20000, 36000, 45000, 55000, length(y)];
To visualize the segment boundaries on the waveform, color code the segments.
figure; hold on; colors = [0 0 1; 0 0.5 0; 1 0 0; 0 0.75 0.75; 0.75 0 0.75]; segStart = [1, segmentEnd(1:end-1)+1]; for k = 1:length(segmentEnd) range = segStart(k):segmentEnd(k); plot(range,y(range),"Color",colors(k,:)); end hold off;

Speaker Configuration
This example assumes that you have a standard 5.1 surround-sound speaker configuration. For this configuration, the channel-to-speaker mapping is:
Channel 1: Left Front
Channel 2: Right Front
Channel 3: Center
Channel 4: Sub-Woofer
Channel 5: Left Rear
Channel 6: Right Rear
Your speaker system might use a different channel ordering. Consult your audio device documentation to confirm the mapping.
Define Speaker Parameters
Set up a selection of speakers in a cell array named speakerselection to play five segments of "Hallelujah" on six different speakers.
nspeakers = 6; nspeakergroups = 5; speakerselection = cell(1,nspeakergroups);
Generate Surround Sound Effect Using Speaker and Sub-Woofer
To produce the effect of sound moving around the room, use the ssurroundSoundVoices helper function, which is defined at the end of this example. The function routes each consecutive segment to a different speaker, paired with the sub-woofer (channel 4).
speakerselection{1} = [4, 6]; % Segment 1: Sub-Woofer + Right Rear
speakerselection{2} = [4, 5]; % Segment 2: Sub-Woofer + Left Rear
speakerselection{3} = [1, 4]; % Segment 3: Left Front + Sub-Woofer
speakerselection{4} = [2, 4]; % Segment 4: Right Front + Sub-Woofer
speakerselection{5} = [3, 4]; % Segment 5: Center + Sub-Woofer
[singleChannelOutputs] = ...
surroundSoundVoices(y,segmentEnd,nspeakers,nspeakergroups,speakerselection);
To play the audio with the surround sound effect, write the single-channel output data to the device. Pause before proceeding to the next effect.
write(dq,singleChannelOutputs); pause(3);
Generate Growing Choir Effect with Speaker Groups
To produce the effect of a growing choir, route each consecutive segment to a larger group of speakers. All groups include the sub-woofer (channel 4).
speakerselection{1} = [4, 5, 6]; % Segment 1: Sub-Woofer + Rear
speakerselection{2} = [1, 2, 4]; % Segment 2: Front Left/Right + Sub-Woofer
speakerselection{3} = [3, 4]; % Segment 3: Center + Sub-Woofer
speakerselection{4} = [1, 2, 3, 4]; % Segment 4: All Front + Sub-Woofer
speakerselection{5} = [1, 2, 3, 4, 5, 6]; % Segment 5: All Speakers
[multiChannelOutput] = ...
surroundSoundVoices(y,segmentEnd,nspeakers,nspeakergroups,speakerselection);
To play the audio with the growing choir effect, write the multichannel output data to the device.
write(dq,multiChannelOutput);
Stereo Alternative
If your audio device supports only two output channels, you can modify this example to work with stereo output. Replace the channel setup with these commands:
numChannels = 2;
addoutput(dq,deviceID,1:numChannels,"Audio");
Then, use a simplified speaker selection for two channels (left and right):
speakerselection{1} = 1; % Left only
speakerselection{2} = 2; % Right only
speakerselection{3} = [1, 2]; % Both
speakerselection{4} = 1; % Left only
speakerselection{5} = [1, 2]; % Both
When calling surroundSoundVoices, adjust nspeakers to 2.
Helper Function
Use the surroundSoundVoices helper function to distribute audio segments across speaker groups. The function breaks the input waveform into contiguous segments defined by segmentEnds, then routes each segment to its assigned group of speakers. Nonactive speakers output a small nonzero baseline value during that segment to keep DirectSound buffers active.
function [multiChannelOutput] = surroundSoundVoices(audioOut,segmentEnds,numSpeakers,numSpeakerGroups,speakerGroups) % To prevent audio dropouts, initialize the output matrix with a small % non-zero value, which keeps DirectSound buffers active on all channels. multiChannelOutput = repmat(0.01,length(audioOut),numSpeakers); startOfSegment = [1 (segmentEnds(1:end-1)+1)]; for i = 1:numSpeakerGroups speakergroup = speakerGroups{i}; n = numel(speakergroup); for j = 1:n range = startOfSegment(i):segmentEnds(i); multiChannelOutput(range, speakergroup(j)) = audioOut(range); end end end