Generating Multichannel Audio
This example shows how to set up continuous audio generation using multiple audio channels. The signal, a sample of Handel's "Hallelujah Chorus", is broken up into contiguous segments and played back in two parts. The first part of the example plays each segment on a single speaker and a sub-woofer. The second part plays each segment on a different set of speakers (a choir of voices).
Load Audio Data
Load Handel's "Hallelujah".
Load variables:
y
representing the Hallelujah waveformFs
representing the sampling frequency
load handel;
Create a Data Acquisition
Create a DataAcquisition object using directsound
as the vendor ID.
dq = daq("directsound")
Add Channels and Adjust Generation Scan Rate to Match the Audio Sampling Frequency
Add six audio output channels and set the generation scan rate to the audio sampling rate.
addoutput(dq,"Audio7",1:6,"Audio"); dq.Rate = Fs;
Plot Audio Data
Visually identify audio segments that correspond to each "Hallelujah" in the chorus and select sample numbers at which these segments start and stop. Each color in the plot corresponds to a different segment of the chorus.
Identify the End of Each Segment
Visually identify the segment boundaries and mark them.
segmentEnd = [20000, 36000, 45000, 55000, length(y)];
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);
Assign Speakers to Groups
Each speaker selection specifies which speakers from the 5.1 channel speaker system play each audio segment (these assignments may vary for your speaker system). For the first part of the example, use single speakers paired with the sub-woofer (4).
Speaker 1: Left-Front
Speaker 2: Right-Front
Speaker 3: Center
Speaker 4: Sub-Woofer
Speaker 5: Left-Rear
Speaker 6: Right-Rear
speakerselection{1} = [4, 6]; % Segment 1; speakers 4 and 6 speakerselection{2} = [4, 5]; % Segment 2; speakers 4 and 5 speakerselection{3} = [1, 4]; % Segment 3; speakers 1 and 4 speakerselection{4} = [2, 4]; % Segment 4; speakers 2 and 4 speakerselection{5} = [3, 4]; % Segment 5; speakers 3 and 4 [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);
Assign Speakers to Groups
Each speaker selection specifies which speakers from the 5.1 channel speaker system play each audio segment (these assignments may vary for your speaker system). For the second part of the example, use groups of speakers. Note that the sub-woofer (4) is included in all speaker selections
Speaker 1: Left-Front
Speaker 2: Right-Front
Speaker 3: Center
Speaker 4: Sub-Woofer
Speaker 5: Left-Rear
Speaker 6: Right-Rear
speakerselection{1} = [4, 5, 6]; % Segment 1; speakers 4, 5, 6 speakerselection{2} = [1, 2, 4]; % Segment 2; speakers 1, 2, 4 speakerselection{3} = [3, 4]; % Segment 3; speakers 3, 4 speakerselection{4} = [1, 2, 3, 4]; % Segment 4; speakers 1, 2, 3, 4 speakerselection{5} = [1, 2, 3, 4, 5, 6]; % Segment 5; all speakers [multiChannelOutput] = ... surroundSoundVoices(y, segmentEnd, nspeakers, nspeakergroups, speakerselection);
Write Multichannel Outputs
write(dq, multiChannelOutput);
function [multiChannelOutput] = surroundSoundVoices(audioOut, segmentEnds, numSpeakers, numSpeakerGroups, speakerGroups) % Distribute contiguous segments of an output waveform to multiple groups % of speakers in a one-to-one relationship. The input waveform is broken up % into contiguous segments. Each segment is output by one and only one % group of speakers, with each group being visited in turn. % Break up the input waveform into segments to be played by various groups % of speakers. In this demonstration, we would like to slowly add "voices" % by incrementally having more speakers generate the output waveform. % In particular, we will regard the output waveform as a contiguous % sequence of segments (one segment per group of speakers). For example, if % we have 3 groups of speakers, we can think of breaking up the output % waveform into 3 segments: output = [s1 s2 s3] % Speaker group 1 outputs: s1 0 0 % Speaker group 2 outputs: 0 s2 0 % Speaker group 3 outputs: 0 0 s3 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