Main Content

Generating Multichannel Audio

R2026b

This example shows how to generate audio signals on multiple output channels using a multichannel audio device. The example plays segments of Handel's "Hallelujah Chorus" through different speaker combinations to create listening effects, such as sound moving around the room and a growing choir.

The example first plays each segment on a single speaker paired with the sub-woofer, and then on progressively larger groups of speakers, simulating a growing choir. This example uses a 5.1 surround-sound audio device. 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 using the addoutput function. Replace "Audio7" with the device ID of your multichannel audio device. You can obtain 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

Plot the audio waveform to visually identify segments corresponding to each "Hallelujah" in the chorus.

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

From the waveform plot, identify the approximate sample indices where each "Hallelujah" segment ends. These values divide the audio into five contiguous segments.

segmentEnd = [20000, 36000, 45000, 55000, length(y)];

Visualize the segment boundaries on the waveform.

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 uses a standard 5.1 surround-sound speaker 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

Each segment plays on one speaker paired with the sub-woofer (channel 4). This produces the effect of the sound moving around the room.

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);

Write Single Channel Outputs

Write a sequence of single channel outputs and then pause before proceeding to the next section.

write(dq,singleChannelOutputs);
pause(3);

Generate Growing Choir Effect with Speaker Groups

Each segment plays on a progressively 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);

Write Multichannel Outputs

Write the sequence of multichannel outputs.

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:

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 and routes each segment to its assigned group of speakers. Non-active speakers output a small non-zero baseline 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