Execute functions and read input simultaneously in Matlab

I have an mp3 file which needs to go through different functions (blocks) in series. The input of each block is taken from the output of the previous block. Block C needs the longest time to process (eg. 10s). The problem is, instead of waiting the 10s, I wish to read another frame of mp3 while waiting the block C to finish its process. Any idea on the solution?

Antworten (2)

Walter Roberson
Walter Roberson am 3 Nov. 2018
Bearbeitet: Walter Roberson am 25 Nov. 2018
If you have the parallel computing toolbox then you can use spmd.
framesize = 4096;
P = parpool(4);
spmd
if labindex == 1
end
end
spmd
if labindex == 1
afr = dsp.AudioFileReader(Filename, 'SamplesPerFrame', framesize);
while ~isDone(afr)
frame = step(afr);
labSend(frame, 2);
end
labSend([], 2)
release(afr)
elseif labindex == 2
while true
frame = labReceive(1);
if isempty(frame)
labSend([], 3)
break
end
Bres = BlockB(frame);
labSend(Bres, 3);
end
elseif labindex == 3
while true
Bres = labReceive(2);
if isempty(Bres)
labSend([], 4)
break
end
Cres = BlockC(Bres) ;
labSend(Cres, 4)
end
else
while true
Cres = labReceive(3);
if isempty(Cres)
break
end
Dres = BlockD(Cres) ;
end
end

11 Kommentare

Thanks Walter. May I know why we need the first spmd loop?
spmd
if labindex == 1
end
end
I had the dsp initialization there but moved it and forgot to remove the step.
Star
Star am 24 Nov. 2018
Bearbeitet: Walter Roberson am 25 Nov. 2018
Hi Walter,
My project goes like this.
labindex1 decode the first 1137 bits (i=0:1137),
labindex2 decode starting from bit #1393 (i=1393:2372)
and labindex3 decode starting from bit #2373 (i=2373:2687).
However, there is a function block in labindex3 which need to retrieve the information of i=0:64. How do I send (i=0:64) from labindex1 to labindex3?
Thank you.
labSend(DataToSend, 3)
And to receive it,
labReceive()
Hi Walter, thanks for the reply.
How to receive a data array by using labReceive()? I have tried three methods but all of them causes an error.
Initialized data array: table_select(1:4,1:3) = uint8(0);
Method #1:
table_select(1:4,1:3) = labReceive(1);
Error:
Error using decoder_spmd_2g4>(spmd body) (line 594)
Error detected on worker 2.
Assignment has fewer non-singleton rhs dimensions than non-singleton subscripts
Method #2:
table_select = labReceive(1);
Error:
Error using decoder_spmd_2g4>(spmd body) (line 705)
Error detected on worker 2.
Attempted to access table_select(1,2); index out of bounds because size(table_select)=[4,1].
Method #3:
table_select(:) = labReceive(1);
Error:
Error using decoder_spmd_2g4>(spmd body) (line 594)
In an assignment A(:) = B, the number of elements in A and B must be the same.
Thank you.
what is size() of the item you labSend() ?
Hi Walter, this is part of my coding:
function [PCM, output] = mp3(song)
table_select(1:4,1:3) = uint8(0);
spmd
if labindex == 1
while true
row_index = 1;
if ( blocksplit_flag(row_index))
for region=1:2
table_select(row_index,region) = uint8( reformbit (y(remd:remd+4)));
end
else
for region=1:3
table_select(row_index,region) = uint8( reformbit (y(remd:remd+4)));
end
labSend(table_select(row_index,:), 2);
end
else labindex == 2
while true
row_index = 1;
table_select(1:4,1:3) = labReceive(1);
if (blocksplit_flag(row_index,1) == 1 && block_type(row_index) == 2)
[a0 lin0 max0] = huffman(table_select(row_index,1));
[a1 lin1 max1] = huffman(table_select(row_index,2));
else
[a0 lin0 max0] = huffman(table_select(row_index,1));
[a1 lin1 max1] = huffman(table_select(row_index,2));
[a2 lin2 max2] = huffman(table_select(row_index,3));
end
end
end
end
end
Thank you.
you are sending a single row but receive into 4 rows. Are you wanting to copy the same one row to all four rows of the matrix ?
Hi Walter, is your answer provided above involve a job scheduler?
No. Job scheduler is only needed if you are using the Distributed Computing Toolbox, which would be for running computing on a cluster. Job schedulers are not required for running only on the resources of the local computer.
Hi Walter, is your answer above considered as Task parallel (Embarrassingly Parallel) or Data parallel (Fine Grained Parallel) ?

Melden Sie sich an, um zu kommentieren.

Star
Star am 5 Dez. 2018
I want to send 4 rows and receive 4 rows. A more detailed coding is shown below:
function [PCM, output] = mp3(song)
table_select(1:4,1:3) = uint8(0);
spmd
if labindex == 1
while true
row_index = 1;
for granule = 1:2
for channel=1:2
if ( blocksplit_flag(row_index))
for region=1:2
table_select(row_index,region) = uint8( reformbit (y(remd:remd+4)));
end
else
for region=1:3
table_select(row_index,region) = uint8( reformbit (y(remd:remd+4)));
end
end
row_index = row_index + 1;
end
end
labSend(table_select(row_index,:), 2);
end
else labindex == 2
while true
table_select(1:4,1:3) = labReceive(1);
row_index = 1;
for granule = 1:2
for channel=1:2
if (blocksplit_flag(row_index,1) == 1 && block_type(row_index) == 2)
[a0 lin0 max0] = huffman(table_select(row_index,1));
[a1 lin1 max1] = huffman(table_select(row_index,2));
else
[a0 lin0 max0] = huffman(table_select(row_index,1));
[a1 lin1 max1] = huffman(table_select(row_index,2));
[a2 lin2 max2] = huffman(table_select(row_index,3));
end
row_index = row_index + 1;
end
end
end
end
end

2 Kommentare

What you labSend is indexed by row so you only send one row .
Thanks Walter.
I have face some problem in labSend. The coding is as below:
function [PCM, output] = mp3(song)
table_select(1:4,1:3) = uint8(0);
spmd
if labindex == 1
while true
%Var b went through several equation
labSend (b1,2);
row_index = 1;
for granule = 1:2
labSend (granule,2);
for channel=1:2
labSend (channel,2);
if ( blocksplit_flag(row_index))
%Went through several equation
for region=1:2
table_select(row_index,region) = uint8( reformbit (y(remd:remd+4)));
labSend(table_select(row_index,:), 2);
end
else
%Went through several equation
for region=1:3
table_select(row_index,region) = uint8( reformbit (y(remd:remd+4)));
labSend(table_select(row_index,:), 2);
remd = remd + 3;
end
end
row_index = row_index + 1;
end %End of channel
end %End of granule
if ( maindata == 0)
b2 = remd;
labSend(b2,2);
labSend(remd,2);
else
b2 = current_bit - (maindata*8);
labSend(b2,2);
labSend(remd,2);
end
end
else labindex == 2
while true
b1 = labReceive(1);
b2 = labReceive(1);
remd = labReceive(1);
if isempty(frameNumber)
labSend(3, []);
break
end
row_index = 1;
for granule = 1:2
for channel=1:2
table_select(1:4,1:3) = labReceive(1);
if (blocksplit_flag(row_index,1) == 1 && block_type(row_index) == 2)
[a0 lin0 max0] = huffman(table_select(row_index,1));
[a1 lin1 max1] = huffman(table_select(row_index,2));
else
[a0 lin0 max0] = huffman(table_select(row_index,1));
[a1 lin1 max1] = huffman(table_select(row_index,2));
[a2 lin2 max2] = huffman(table_select(row_index,3));
end
row_index = row_index + 1;
end %End of channel
end %End of granule
end
end
end
My Questions are:
1. I manage to labReceive b1 but not b2 and remd. The value for b2 and remd is always zero.
Is it because of the for loop that cause b2 and remd cannot be received?
2. labindex 2 always come first before labindex 1.
I think it is because of the preset value of granule and channel.
How to make labindex 1 run first so that the data needed can be received by labindex 2?
I have tried to run the coding below but it could not work.
Again, the value of granule and channel are always zero.
row_index = labReceive(1);
row_index = row_index + 0;
granule = labReceive(1);
for ( 0 < granule < 3)
disp(sprintf('This is granule %d', granule));
channel = labReceive(1);
for ( 0 < channel < 3)
disp(sprintf('This is channel %d', channel));
%Content
end
end
Thank you.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Startup and Shutdown finden Sie in Hilfe-Center und File Exchange

Produkte

Gefragt:

am 3 Nov. 2018

Kommentiert:

am 10 Apr. 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by