Main Content

Generate Multichannel Audio

R2026b

This 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

See Also

Functions

Topics