On Mar 17, 2009, at 12:46 PM, vlimhamm wrote:
This looks all way too convoluted and i don't want to go through your
whole code, so just the basics:
with nrOfFiles == number of sound files to load: nrOfFiles should be
probably rather = length(WavesH), instead of length(files), ie.,
match the number of names in WavesH and not the number of files in
the directory, otherwise you're in for weird errors on the slightest
mismatch between both.
for c=1:nrOfFiles
y= wavread([WavesH{1,1}{c,1}]);
soundH{c} = y' ;
end
-> Store mono (1-channel) sound vector of file with name WavesH{1,1}
{c,1} in slot c of cell array soundH.
-> No need to store freq{c} as i assume all your wav files have the
same sample rate anyway and you hard-coded this already to
'samplerate = 44100'.
-> Btw. this WavesH{1,1}{c,1} already looks pretty weird. Shouldn't
WavesH{c} do the same if textscan is used properly?
-> Make sure that all your wav files have the same number of samples,
so you don't need to take care of padding data vectors with zeros ->
One less complication.
Then repeat the same procedure for loading WavesL.
After this you'll have all data in memory. Later on you can build
your 2-channel stereo vectors:
for c=1:n
% Put soundH{c} in channel 1 and soundL{c} in channel 2 --> Simply
concatenate them together, each goes into one row of the 2-by-
numberofsamples matrix.
% Assign this matrix to slot {c} of cell array OutSound.
OutSound{c} = [ soundH{c} ; soundL{c} ];
end
Your randomization of 'n' trials with TOrder = randperm(n); is
correct, but of course you then must use TOrder(c) instead of c later
on for indexing!
Down in the playback loop you'd do
PsychPortAudio('FillBuffer', pahandle, OutSound{ TOrder(c) });
-> First index into TOrder at slot 'c' to lookup the permutated index
TOrder(c) of the sound to play. Then read out the content of slot
{TOrder(c)} from the cell array OutSound. The content of this slot
will be the 2-channel matrix you've stored there earlier -> exactly
the input that PsychPortAudio wants.
This should get you going but it is not a really efficient method. It
consumes about 2x the amount of system memory, because each wav file
is now stored twice in memory, once in a slot of the soundH or soundL
cell array and once in a 2D matrix inside a slot of the OutSound cell
array. If you have many wav files that are large, it can get you
quickly into out-of-memory trouble.
E.g., Each sample consumes 8 bytes, so a 1 second sound at 44100 Hz
would consume about 0.34 Megabytes per wav file.
A more efficient approach would be to either only store the combined
2-channel OutSound array or only the separate soundH and soundL data.
E.g., if you know that each wav file is only used exactly once in one
trial you could get rid of the soundH and soundL step and instead
directly build the OutSound{c} at load time:
for c=1:nrOfFiles
% Read WavesH into soundH vector:
y = wavread([WavesH{1,1}{c,1}]);
soundH = y' ;
% Read WavesL into soundL vector:
y = wavread([WavesL{1,1}{c,1}]);
soundL = y' ;
% Immediately assembe soundH and soundL into the final OutSound{c}
slot of cell array OutSound:
OutSound{c} = [ soundH ; soundL ];
end
I'd strongly recommend you read through the sections about
"Programming -> Data Types -> Cell arrays" in Matlabs online help.
The "Programming" section in Matlabs online help is well written and
beginners really should read at least the basic sections in there. A
few hours of reading will save you many weeks of lost time in the
long run.
The Psychtoolbox forum can't be a replacement for a Matlab
programming course or book and i usually don't respond to programming
questions unrelated to PTB. Your question here boils down to "how do
i use cell arrays and matrices correctly"?
best,
-mario
Mario Kleiner
Max Planck Institute for Biological Cybernetics
Spemannstr. 38
72076 Tuebingen
Germany
e-mail: mario.kleiner@...
office: +49 (0)7071/601-1623
fax: +49 (0)7071/601-616
www: http://www.kyb.tuebingen.mpg.de/~kleinerm
*********************************************************************
"For a successful technology, reality must take precedence
over public relations, for Nature cannot be fooled."
(Richard Feynman)
> Hi Mario,Hi Vanessa
>
> I posted this message on the board and I was wondering if you had a
> chance to look at it please? I would greatly appreciate any tips
> you have! I also posted on matlab community but no one has replied
> as well.
>
> Many thanks, I look forward to hearing from you.
> Best regards,
> Vanessa
This looks all way too convoluted and i don't want to go through your
whole code, so just the basics:
> [y{c}, freq{c}]= wavread([WavesH{1,1}{c,1}]);In your loading loop do something like this:
> [WavesH{1,1}{c,1}] = y{c}';
with nrOfFiles == number of sound files to load: nrOfFiles should be
probably rather = length(WavesH), instead of length(files), ie.,
match the number of names in WavesH and not the number of files in
the directory, otherwise you're in for weird errors on the slightest
mismatch between both.
for c=1:nrOfFiles
y= wavread([WavesH{1,1}{c,1}]);
soundH{c} = y' ;
end
-> Store mono (1-channel) sound vector of file with name WavesH{1,1}
{c,1} in slot c of cell array soundH.
-> No need to store freq{c} as i assume all your wav files have the
same sample rate anyway and you hard-coded this already to
'samplerate = 44100'.
-> Btw. this WavesH{1,1}{c,1} already looks pretty weird. Shouldn't
WavesH{c} do the same if textscan is used properly?
-> Make sure that all your wav files have the same number of samples,
so you don't need to take care of padding data vectors with zeros ->
One less complication.
Then repeat the same procedure for loading WavesL.
After this you'll have all data in memory. Later on you can build
your 2-channel stereo vectors:
for c=1:n
% Put soundH{c} in channel 1 and soundL{c} in channel 2 --> Simply
concatenate them together, each goes into one row of the 2-by-
numberofsamples matrix.
% Assign this matrix to slot {c} of cell array OutSound.
OutSound{c} = [ soundH{c} ; soundL{c} ];
end
Your randomization of 'n' trials with TOrder = randperm(n); is
correct, but of course you then must use TOrder(c) instead of c later
on for indexing!
Down in the playback loop you'd do
PsychPortAudio('FillBuffer', pahandle, OutSound{ TOrder(c) });
-> First index into TOrder at slot 'c' to lookup the permutated index
TOrder(c) of the sound to play. Then read out the content of slot
{TOrder(c)} from the cell array OutSound. The content of this slot
will be the 2-channel matrix you've stored there earlier -> exactly
the input that PsychPortAudio wants.
This should get you going but it is not a really efficient method. It
consumes about 2x the amount of system memory, because each wav file
is now stored twice in memory, once in a slot of the soundH or soundL
cell array and once in a 2D matrix inside a slot of the OutSound cell
array. If you have many wav files that are large, it can get you
quickly into out-of-memory trouble.
E.g., Each sample consumes 8 bytes, so a 1 second sound at 44100 Hz
would consume about 0.34 Megabytes per wav file.
A more efficient approach would be to either only store the combined
2-channel OutSound array or only the separate soundH and soundL data.
E.g., if you know that each wav file is only used exactly once in one
trial you could get rid of the soundH and soundL step and instead
directly build the OutSound{c} at load time:
for c=1:nrOfFiles
% Read WavesH into soundH vector:
y = wavread([WavesH{1,1}{c,1}]);
soundH = y' ;
% Read WavesL into soundL vector:
y = wavread([WavesL{1,1}{c,1}]);
soundL = y' ;
% Immediately assembe soundH and soundL into the final OutSound{c}
slot of cell array OutSound:
OutSound{c} = [ soundH ; soundL ];
end
I'd strongly recommend you read through the sections about
"Programming -> Data Types -> Cell arrays" in Matlabs online help.
The "Programming" section in Matlabs online help is well written and
beginners really should read at least the basic sections in there. A
few hours of reading will save you many weeks of lost time in the
long run.
The Psychtoolbox forum can't be a replacement for a Matlab
programming course or book and i usually don't respond to programming
questions unrelated to PTB. Your question here boils down to "how do
i use cell arrays and matrices correctly"?
best,
-mario
>*********************************************************************
>
> I have got 2 separate files working now, but how do you do multiple
> ones? and
> randomise the order? The way I originally had it...
>
> clear all;
> n=5; % number of trials/files you have
> nrchannels = 2; % you have 2 channels, left and right ears/or 2 ipsi/
> repetitions = 1; % only play wave files once
> samplerate = 44100;
> 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', ';');
> cd Hwav;
> c = 0;
> files = dir('*wav');
> for c=1:length(files);
> [y{c}, freq{c}]= wavread([WavesH{1,1}{c,1}]);
> [WavesH{1,1}{c,1}] = y{c}';
> end
> cd ..;
>
> cd Lwav;
> c = 0;
> files = dir('*wav');
> for c=1:length(files);
> [y{c}, freq{c}]= wavread([WavesL{1,1}{c,1}]);
> [WavesL{1,1}{c,1}] = y{c}';
>
> end
> cd ..;
>
> % is the above correct??? this allowed me to read in the wavefiles
> % and index them
> %-------------------------------------
> % Randomisation
> %-------------------------------------
> TOrder = randperm(n);
> InitializePsychSound(1);
> c = 0;
>
> % below is where I am unsure of the structure being correct, there
> is %no error
> here but I can't index it in the fillbuffer call
>
> disp('Which channel for High? 1 or 2 where 1 = Left; 2 = Right: ');
> ChannelResp = input('Channel: ');
> ChannelStore = ChannelResp;
> if ChannelResp == 1
> for c=1:n
> [OutSound(2,:).c]=[WavesL{1,1}{c,1}];
> [OutSound(1,:).c]=[WavesH{1,1}{c,1}];
> end
> else
> for c=1:n
> [OutSound(2,:).c]= [WavesH{1,1}{c,1}];
> [OutSound(1,:).c]= [WavesL{1,1}{c,1}];
> end
> end
>
> pahandle = PsychPortAudio('Open', [], [], 1, samplerate, nrchannels);
> c = 0;
> for c = 1:n
>
> %I've tried all sorts of combinations of [OutSound(:,:).{c}] etc
> %but this doesn't work
> %I also tried to make ThisSound into the trial OutSound but this
> doesn't work
>
> ThisSound = OutSound(:,:,c);
> PsychPortAudio('FillBuffer', pahandle, ThisSound);
> P1 = PsychPortAudio('Start', pahandle, repetitions, 0, 1);
>
> PsychPortAudio('Stop', pahandle, 1);
>
> end
>
> It can read the wavefiles, but I can't get OutSound to work because
> I am unsure
> if this is the correct way to read the files in to work with the
> toolbox.
>
> Also, In order to randomise the order of the wavefiles in my
> previous version I
> could index pahandle and I could use the TOrder (randompermation
> from above) to
> get a random trial. How do I do this when pahandle can't be indexed
> please?
>
> %PsychPortAudio('FillBuffer', [pahandle{1,1}{[TOrder(1,c)],1}],
> OutSound);
> %P1 = PsychPortAudio('Start', [pahandle{1,1}{[TOrder(1,c)],1}],
> repetitions, 0, 1); % play the High freq wave files
>
> Thank you for your help! I got this to initialise on my PC now
> thanks! It
> doesn't seem to crash like it did yesterday.
>
> Many thanks,
> Vanessa
>
>
Mario Kleiner
Max Planck Institute for Biological Cybernetics
Spemannstr. 38
72076 Tuebingen
Germany
e-mail: mario.kleiner@...
office: +49 (0)7071/601-1623
fax: +49 (0)7071/601-616
www: http://www.kyb.tuebingen.mpg.de/~kleinerm
*********************************************************************
"For a successful technology, reality must take precedence
over public relations, for Nature cannot be fooled."
(Richard Feynman)