multiple wav files read in

Hi,
I am trying to read in multiple wav files (2 channels separately but simultaneously),
randomise them and play them back.

I can play 2 files which seem simultaneous
wavfilename1 = 'files1H.wav';
[y, freqH]= wavread(wavfilename1);
wavedataH = y';
nrchannelsH = size(wavedataH,1);
wavfilename2 = 'files1L.wav';
[y, freqL]= wavread(wavfilename2);
wavedataL = y';
nrchannelsL = size(wavedataL,1);
pahandleH = PsychPortAudio('Open', [], [], 1, freqH, nrchannelsH);
pahandleL = PsychPortAudio('Open', [], [], 1, freqL, nrchannelsL);
PsychPortAudio('FillBuffer', pahandleH, wavedataH );
PsychPortAudio('FillBuffer', pahandleL, wavedataL );
H1 = PsychPortAudio('Start', pahandleH, 1, 0, 1);
L1 = PsychPortAudio('Start', pahandleL, 1, 0, 1);
close etc.

But I have 400 files that I need to read in (200 in left and 200 in the right channels) so I
can't "hard" code this.

I tried below but this doesn't work - where the wavefile names have been read in from a
text file
wavfilename(n) = WavesH(n);
[y(n), freqH(n)]= wavread(wavfilename(n));
wavedataH(n) = y(n)';
nrchannelsH(n) = size(wavedataH(n),1);

Ideally it would be great to read them into an array, randomise and then call them when
needed.

Sorry, I'm new to matlab and psychtoolbox, after years of turbo pascal, technology has
moved along, so must I....
Many thanks,
Vanessa
Hi Vanessa,

Just a quick pointer that might get you further: look into the cell,
datatype in matlab. For all those calls which return an array in the
working code you showed us, when you rewrite that to the code to read
in 200 files, you would probably want to rewrite that using cells.
Using cells, you can create an array of arrays (where the internal
arrays do not have to be of the same length or shape).

so, for instance (i believe wavread returns arrays), try: [y{n},
freqH{n}]= wavread([...]); Notice the curly braces instead of normal
ones.

Hope this gets you further,

Diederick

On Fri, Feb 27, 2009 at 9:18 PM, vlimhamm <vlim003@...> wrote:
> Hi,
> I am trying to read in multiple wav files (2 channels separately but
> simultaneously),
> randomise them and play them back.
>
> I can play 2 files which seem simultaneous
> wavfilename1 = 'files1H.wav';
> [y, freqH]= wavread(wavfilename1);
> wavedataH = y';
> nrchannelsH = size(wavedataH,1);
> wavfilename2 = 'files1L.wav';
> [y, freqL]= wavread(wavfilename2);
> wavedataL = y';
> nrchannelsL = size(wavedataL,1);
> pahandleH = PsychPortAudio('Open', [], [], 1, freqH, nrchannelsH);
> pahandleL = PsychPortAudio('Open', [], [], 1, freqL, nrchannelsL);
> PsychPortAudio('FillBuffer', pahandleH, wavedataH );
> PsychPortAudio('FillBuffer', pahandleL, wavedataL );
> H1 = PsychPortAudio('Start', pahandleH, 1, 0, 1);
> L1 = PsychPortAudio('Start', pahandleL, 1, 0, 1);
> close etc.
>
> But I have 400 files that I need to read in (200 in left and 200 in the
> right channels) so I
> can't "hard" code this.
>
> I tried below but this doesn't work - where the wavefile names have been
> read in from a
> text file
> wavfilename(n) = WavesH(n);
> [y(n), freqH(n)]= wavread(wavfilename(n));
> wavedataH(n) = y(n)';
> nrchannelsH(n) = size(wavedataH(n),1);
>
> Ideally it would be great to read them into an array, randomise and then
> call them when
> needed.
>
> Sorry, I'm new to matlab and psychtoolbox, after years of turbo pascal,
> technology has
> moved along, so must I....
> Many thanks,
> Vanessa
>
>
Hi Diederick,

Thank you. This works!

WavesH = textscan(fidWaveTxtH, '%s', 'delimiter', ';');

cd Hwav;
c = 0;
files = dir('*wav');
for c=1:length(files);
[y{c}, freqH{c}]= wavread([WavesH{1,1}{c,1}])
[WavesH{1,1}{c,1}] = y{c}'
[nrchannelsH{1,1}{c,1}] = size([WavesH{1,1}{c,1}],1);
end
cd ..;

Cheers,
Vanessa!!! Now working on the randomisation :)

--- In psychtoolbox@yahoogroups.com, "Diederick C. Niehorster" <dcnieho@...> wrote:
>
> Hi Vanessa,
>
> Just a quick pointer that might get you further: look into the cell,
> datatype in matlab. For all those calls which return an array in the
> working code you showed us, when you rewrite that to the code to read
> in 200 files, you would probably want to rewrite that using cells.
> Using cells, you can create an array of arrays (where the internal
> arrays do not have to be of the same length or shape).
>
> so, for instance (i believe wavread returns arrays), try: [y{n},
> freqH{n}]= wavread([...]); Notice the curly braces instead of normal
> ones.
>
> Hope this gets you further,
>
> Diederick
>
> On Fri, Feb 27, 2009 at 9:18 PM, vlimhamm <vlim003@...> wrote:
> > Hi,
> > I am trying to read in multiple wav files (2 channels separately but
> > simultaneously),
> > randomise them and play them back.
> >
> > I can play 2 files which seem simultaneous
> > wavfilename1 = 'files1H.wav';
> > [y, freqH]= wavread(wavfilename1);
> > wavedataH = y';
> > nrchannelsH = size(wavedataH,1);
> > wavfilename2 = 'files1L.wav';
> > [y, freqL]= wavread(wavfilename2);
> > wavedataL = y';
> > nrchannelsL = size(wavedataL,1);
> > pahandleH = PsychPortAudio('Open', [], [], 1, freqH, nrchannelsH);
> > pahandleL = PsychPortAudio('Open', [], [], 1, freqL, nrchannelsL);
> > PsychPortAudio('FillBuffer', pahandleH, wavedataH );
> > PsychPortAudio('FillBuffer', pahandleL, wavedataL );
> > H1 = PsychPortAudio('Start', pahandleH, 1, 0, 1);
> > L1 = PsychPortAudio('Start', pahandleL, 1, 0, 1);
> > close etc.
> >
> > But I have 400 files that I need to read in (200 in left and 200 in the
> > right channels) so I
> > can't "hard" code this.
> >
> > I tried below but this doesn't work - where the wavefile names have been
> > read in from a
> > text file
> > wavfilename(n) = WavesH(n);
> > [y(n), freqH(n)]= wavread(wavfilename(n));
> > wavedataH(n) = y(n)';
> > nrchannelsH(n) = size(wavedataH(n),1);
> >
> > Ideally it would be great to read them into an array, randomise and then
> > call them when
> > needed.
> >
> > Sorry, I'm new to matlab and psychtoolbox, after years of turbo pascal,
> > technology has
> > moved along, so must I....
> > Many thanks,
> > Vanessa
> >
> >
>
Hi Mario,

It sounds like I am using the port wrong then? Am I opening up (in this example) 5 audio devices? I haven't tested it with more than 5 yet as I assummed it would work. Have I done this right?
Also, I really need to be able to specify a Left channel (monaural presentations) for 1 wave file and right channel for another wave file. How do I do this please?
I am running on a mac, but I can run using a PC. Although when I ran the same code I have on the mac on the PC it wouldn't run and had heaps of errors, so if I can get the mac to do monaural presentation that would be alot easier!
Many thanks, I greatly appreciate the help of the forum!
Regards,
Vanessa

clear all;
n=5; % number of trials/files you have

%-------------------------------------
% Text files Set up: Sentences & Wavefile names
%-------------------------------------
fidTxt = fopen('5HintSent.txt');
Sent = textscan(fidTxt, '%s', 'delimiter', ';'); % need fopen to use textscan, reads array of strings with the delimiter ; as the end of the cell
fidWaveTxtH = fopen('WaveHfiles.txt');
WavesH = textscan(fidWaveTxtH, '%s', 'delimiter', ';'); % need fopen to use textscan, reads array of strings with the delimiter ; as the end of the cell
fidWaveTxtL = fopen('WaveLfiles.txt');
WavesL = textscan(fidWaveTxtL, '%s', 'delimiter', ';');
%-------------------------------------
% Actual Wavefiles
%-------------------------------------
cd Hwav;
c = 0;
files = dir('*wav');
for c=1:length(files);
[y{c}, freqH{c}]= wavread([WavesH{1,1}{c,1}]);
[WavesH{1,1}{c,1}] = y{c}';
[nrchannelsH{1,1}{c,1}] = size([WavesH{1,1}{c,1}],1);
end
cd ..;

cd Lwav;
c = 0;
files = dir('*wav');
for c=1:length(files);
[y{c}, freqL{c}]= wavread([WavesL{1,1}{c,1}]);
[WavesL{1,1}{c,1}] = y{c}';
[nrchannelsL{1,1}{c,1}] = size([WavesL{1,1}{c,1}],1);
end
cd ..;

%-------------------------------------
% Randomisation
%-------------------------------------
TOrder = randperm(n); % array works TOrder 1 2 3 4 5 goes to e.g: 5 4 3 1 2 to call see below [TOrder(1,c)] where c is the counter
% e.g. if you call [TOrder(1,2)] it will give you 4 in this particular example; [TOrder(1,4)] = 1
%-------------------------------------
% Initialisation of sound driver
%-------------------------------------
% you need to download Psychtoolbox which must have psychportaudio
InitializePsychSound(1);

c = 0;
for c = 1:n;
[pahandleH{1,1}{c,1}] = PsychPortAudio('Open', [], [], 1, freqH{c}, [nrchannelsH{1,1}{c,1}]);
[pahandleL{1,1}{c,1}] = PsychPortAudio('Open', [], [], 1, freqL{c}, [nrchannelsL{1,1}{c,1}]);
PsychPortAudio('FillBuffer', [pahandleH{1,1}{c,1}], [WavesH{1,1}{c,1}]);
PsychPortAudio('FillBuffer', [pahandleL{1,1}{c,1}], [WavesL{1,1}{c,1}]);
end


%-------------------------------------
% Main Experiment
%-------------------------------------
c = 0;
for c = 1:n
H1 = PsychPortAudio('Start', [pahandleH{1,1}{[TOrder(1,c)],1}], 1, 0, 1); % play the High freq wave files
L1 = PsychPortAudio('Start', [pahandleL{1,1}{[TOrder(1,c)],1}], 1, 0, 1); % play the low freq wave files
disp(Sent{1,1}{[TOrder(1,c)],1}) % display the sentence

Resp = input('Response or ~ to escape: ','s') % get sub response
RespStore(c) = cellstr(Resp);
RespStore2 = char(RespStore(c)); % change the response to check for ~ quit key here
if (RespStore2) == ('~')
break;
end

PsychPortAudio('Stop', [pahandleH{1,1}{[TOrder(1,c)],1}], 1);
PsychPortAudio('Stop', [pahandleL{1,1}{[TOrder(1,c)],1}], 1);
end





%-------------------------------------
% Close devices and screens
%-------------------------------------
c = 0;
for c = 1:n
PsychPortAudio('Close', [pahandleH{1,1}{c,1}]);
PsychPortAudio('Close', [pahandleL{1,1}{c,1}]);
end

Screen('CloseAll');



--- In psychtoolbox@yahoogroups.com, "Mario Kleiner" <mario.kleiner@...> wrote:
>
> Hi,
>
> one more tip: You should not open one audio device for
> each wavfile. That will not work, because we have a limit
> of about 10 open devices (or maybe 100, can't remember),
> as this consumes a lot of system ressources. Some operating
> systems don't even allow opening multiple devices, so your
> code becomes non-portable. The idea is to have 1 open
> PsychPortAuido device for each real soundcard in your system.
>
> Instead you'd read the wavfiles into a cell array or similar,
> as suggested. In your trial loop at the start of each trial you'd
> PsychPortAudio('FillBuffer', ...); that specific cell array entry
> into the sound buffer of your single open audio device.
>
> This is fast enough for most purposes. We have more
> elaborate ways if if isn't an option. An upcoming PsychPortAudio
> release will also have a new function that allows to have
> multiple predefined soundbuffers.
>
> best,
> -mario
>
>
> --- In psychtoolbox@yahoogroups.com, "vlimhamm" <vlim003@> wrote:
> >
> > Hi,
> > I am trying to read in multiple wav files (2 channels separately but simultaneously),
> > randomise them and play them back.
> >
> > I can play 2 files which seem simultaneous
> > wavfilename1 = 'files1H.wav';
> > [y, freqH]= wavread(wavfilename1);
> > wavedataH = y';
> > nrchannelsH = size(wavedataH,1);
> > wavfilename2 = 'files1L.wav';
> > [y, freqL]= wavread(wavfilename2);
> > wavedataL = y';
> > nrchannelsL = size(wavedataL,1);
> > pahandleH = PsychPortAudio('Open', [], [], 1, freqH, nrchannelsH);
> > pahandleL = PsychPortAudio('Open', [], [], 1, freqL, nrchannelsL);
> > PsychPortAudio('FillBuffer', pahandleH, wavedataH );
> > PsychPortAudio('FillBuffer', pahandleL, wavedataL );
> > H1 = PsychPortAudio('Start', pahandleH, 1, 0, 1);
> > L1 = PsychPortAudio('Start', pahandleL, 1, 0, 1);
> > close etc.
> >
> > But I have 400 files that I need to read in (200 in left and 200 in the right channels) so I
> > can't "hard" code this.
> >
> > I tried below but this doesn't work - where the wavefile names have been read in from a
> > text file
> > wavfilename(n) = WavesH(n);
> > [y(n), freqH(n)]= wavread(wavfilename(n));
> > wavedataH(n) = y(n)';
> > nrchannelsH(n) = size(wavedataH(n),1);
> >
> > Ideally it would be great to read them into an array, randomise and then call them when
> > needed.
> >
> > Sorry, I'm new to matlab and psychtoolbox, after years of turbo pascal, technology has
> > moved along, so must I....
> > Many thanks,
> > Vanessa
> >
>
Yes you are using it suboptimal, and no you only
seem to call PsychPortAudio('Open',...) twice, so
you're opening 2 devices, not 5.

Still one too much. We allow you to open 10 or
100 devices, if i remember correctly, and OS/X
will allow this. But depending on settings, Windows
or Linux may or may not allow this, so your code
becomes non-portable. Even on OS/X it wastes
ressources if you open multiple devices for no
important reason.

Most efficient is to PsychPortAudio('Open') one
device at the beginning of your script, and
PsychPortAudio('Close') it at the end.

Within each trial you'd have a sequence:

1.PsychPortAudio('Fillbuffer', ....);
2.PsychPortAudio('Start',...);
3....whatever...
4.PsychPortAudio('Stop',...);
5. goto 1 for next trial.

You would always open the device with
2 channels, so the 'FillBuffer' call expects
a 2-row by n samples matrix (row 1 = channel1,
row2 = channel2) for output.

for stereo you set the two channels to
appropriate content. for mono, you simply
only fill one of the channels with content and
fill the other channel with zeros, so it outputs
silence.

e.g., if "myleftsound" is a one row sound vector
to be output solely to channel 1, you'd call:

outsound(1,:) = myleftsound;
outsound(2,:) = 0; % Fill channel two with silence...
PsychPortAudio('Fillbuffer', pahandle, outsound);

What you wanted to achieve is having multiple
soundbuffers. This feature will only be added to
a future driver release, but the "News" page on
the Wiki contains some info about new features
of PsychPortAudio that may be useful to you.

Your code requests low-latency mode due to the
1-flag in PsychPortAudio('Open', [], [], 1, freqH{c},...

for reliable low-latency mode on MS-Windows
you'll need an ASIO capable soundcard with proper
drivers, otherwise it'll be unreliable. See the
Wiki for that info as well. (hardwaresupport->audiostuff...)

-mario





[pahandleH{1,1}{c,1}] = PsychPortAudio('Open', [], [], 1, freqH{c},
[nrchannelsH{1,1}{c,1}]);
[pahandleL{1,1}{c,1}] = PsychPortAudio('Open', [], [], 1, freqL{c},
[nrchannelsL{1,1}{c,1}]);

--- In psychtoolbox@yahoogroups.com, "vlimhamm" <vlim003@...> wrote:
>
> Hi Mario,
>
> It sounds like I am using the port wrong then? Am I opening up (in this example) 5 audio devices? I haven't tested it with more than 5 yet as I assummed it would work. Have I done this right?
> Also, I really need to be able to specify a Left channel (monaural presentations) for 1 wave file and right channel for another wave file. How do I do this please?
> I am running on a mac, but I can run using a PC. Although when I ran the same code I have on the mac on the PC it wouldn't run and had heaps of errors, so if I can get the mac to do monaural presentation that would be alot easier!
> Many thanks, I greatly appreciate the help of the forum!
> Regards,
> Vanessa
>
> clear all;
> n=5; % number of trials/files you have
>
> %-------------------------------------
> % Text files Set up: Sentences & Wavefile names
> %-------------------------------------
> fidTxt = fopen('5HintSent.txt');
> Sent = textscan(fidTxt, '%s', 'delimiter', ';'); % need fopen to use textscan, reads array of strings with the delimiter ; as the end of the cell
> fidWaveTxtH = fopen('WaveHfiles.txt');
> WavesH = textscan(fidWaveTxtH, '%s', 'delimiter', ';'); % need fopen to use textscan, reads array of strings with the delimiter ; as the end of the cell
> fidWaveTxtL = fopen('WaveLfiles.txt');
> WavesL = textscan(fidWaveTxtL, '%s', 'delimiter', ';');
> %-------------------------------------
> % Actual Wavefiles
> %-------------------------------------
> cd Hwav;
> c = 0;
> files = dir('*wav');
> for c=1:length(files);
> [y{c}, freqH{c}]= wavread([WavesH{1,1}{c,1}]);
> [WavesH{1,1}{c,1}] = y{c}';
> [nrchannelsH{1,1}{c,1}] = size([WavesH{1,1}{c,1}],1);
> end
> cd ..;
>
> cd Lwav;
> c = 0;
> files = dir('*wav');
> for c=1:length(files);
> [y{c}, freqL{c}]= wavread([WavesL{1,1}{c,1}]);
> [WavesL{1,1}{c,1}] = y{c}';
> [nrchannelsL{1,1}{c,1}] = size([WavesL{1,1}{c,1}],1);
> end
> cd ..;
>
> %-------------------------------------
> % Randomisation
> %-------------------------------------
> TOrder = randperm(n); % array works TOrder 1 2 3 4 5 goes to e.g: 5 4 3 1 2 to call see below [TOrder(1,c)] where c is the counter
> % e.g. if you call [TOrder(1,2)] it will give you 4 in this particular example; [TOrder(1,4)] = 1
> %-------------------------------------
> % Initialisation of sound driver
> %-------------------------------------
> % you need to download Psychtoolbox which must have psychportaudio
> InitializePsychSound(1);
>
> c = 0;
> for c = 1:n;
> [pahandleH{1,1}{c,1}] = PsychPortAudio('Open', [], [], 1, freqH{c}, [nrchannelsH{1,1}{c,1}]);
> [pahandleL{1,1}{c,1}] = PsychPortAudio('Open', [], [], 1, freqL{c}, [nrchannelsL{1,1}{c,1}]);
> PsychPortAudio('FillBuffer', [pahandleH{1,1}{c,1}], [WavesH{1,1}{c,1}]);
> PsychPortAudio('FillBuffer', [pahandleL{1,1}{c,1}], [WavesL{1,1}{c,1}]);
> end
>
>
> %-------------------------------------
> % Main Experiment
> %-------------------------------------
> c = 0;
> for c = 1:n
> H1 = PsychPortAudio('Start', [pahandleH{1,1}{[TOrder(1,c)],1}], 1, 0, 1); % play the High freq wave files
> L1 = PsychPortAudio('Start', [pahandleL{1,1}{[TOrder(1,c)],1}], 1, 0, 1); % play the low freq wave files
> disp(Sent{1,1}{[TOrder(1,c)],1}) % display the sentence
>
> Resp = input('Response or ~ to escape: ','s') % get sub response
> RespStore(c) = cellstr(Resp);
> RespStore2 = char(RespStore(c)); % change the response to check for ~ quit key here
> if (RespStore2) == ('~')
> break;
> end
>
> PsychPortAudio('Stop', [pahandleH{1,1}{[TOrder(1,c)],1}], 1);
> PsychPortAudio('Stop', [pahandleL{1,1}{[TOrder(1,c)],1}], 1);
> end
>
>
>
>
>
> %-------------------------------------
> % Close devices and screens
> %-------------------------------------
> c = 0;
> for c = 1:n
> PsychPortAudio('Close', [pahandleH{1,1}{c,1}]);
> PsychPortAudio('Close', [pahandleL{1,1}{c,1}]);
> end
>
> Screen('CloseAll');
>
>
>
> --- In psychtoolbox@yahoogroups.com, "Mario Kleiner" <mario.kleiner@> wrote:
> >
> > Hi,
> >
> > one more tip: You should not open one audio device for
> > each wavfile. That will not work, because we have a limit
> > of about 10 open devices (or maybe 100, can't remember),
> > as this consumes a lot of system ressources. Some operating
> > systems don't even allow opening multiple devices, so your
> > code becomes non-portable. The idea is to have 1 open
> > PsychPortAuido device for each real soundcard in your system.
> >
> > Instead you'd read the wavfiles into a cell array or similar,
> > as suggested. In your trial loop at the start of each trial you'd
> > PsychPortAudio('FillBuffer', ...); that specific cell array entry
> > into the sound buffer of your single open audio device.
> >
> > This is fast enough for most purposes. We have more
> > elaborate ways if if isn't an option. An upcoming PsychPortAudio
> > release will also have a new function that allows to have
> > multiple predefined soundbuffers.
> >
> > best,
> > -mario
> >
> >
> > --- In psychtoolbox@yahoogroups.com, "vlimhamm" <vlim003@> wrote:
> > >
> > > Hi,
> > > I am trying to read in multiple wav files (2 channels separately but simultaneously),
> > > randomise them and play them back.
> > >
> > > I can play 2 files which seem simultaneous
> > > wavfilename1 = 'files1H.wav';
> > > [y, freqH]= wavread(wavfilename1);
> > > wavedataH = y';
> > > nrchannelsH = size(wavedataH,1);
> > > wavfilename2 = 'files1L.wav';
> > > [y, freqL]= wavread(wavfilename2);
> > > wavedataL = y';
> > > nrchannelsL = size(wavedataL,1);
> > > pahandleH = PsychPortAudio('Open', [], [], 1, freqH, nrchannelsH);
> > > pahandleL = PsychPortAudio('Open', [], [], 1, freqL, nrchannelsL);
> > > PsychPortAudio('FillBuffer', pahandleH, wavedataH );
> > > PsychPortAudio('FillBuffer', pahandleL, wavedataL );
> > > H1 = PsychPortAudio('Start', pahandleH, 1, 0, 1);
> > > L1 = PsychPortAudio('Start', pahandleL, 1, 0, 1);
> > > close etc.
> > >
> > > But I have 400 files that I need to read in (200 in left and 200 in the right channels) so I
> > > can't "hard" code this.
> > >
> > > I tried below but this doesn't work - where the wavefile names have been read in from a
> > > text file
> > > wavfilename(n) = WavesH(n);
> > > [y(n), freqH(n)]= wavread(wavfilename(n));
> > > wavedataH(n) = y(n)';
> > > nrchannelsH(n) = size(wavedataH(n),1);
> > >
> > > Ideally it would be great to read them into an array, randomise and then call them when
> > > needed.
> > >
> > > Sorry, I'm new to matlab and psychtoolbox, after years of turbo pascal, technology has
> > > moved along, so must I....
> > > Many thanks,
> > > Vanessa
> > >
> >
>