Clear Filters
Clear Filters

Why am I unable to add these elements to an array?

3 views (last 30 days)
I'm currently working on a project where I am creating music from the intensities of an image, and I'm able to produce the overall sounds through a for loop, but I am running into a new error -- I am trying to take all of these frequencies and write them using audiowrite, but I am getting an error that says "Unable to perform assignment because the size of the left side is 1-by-4096 and the size of the right side is 1-by-8192." I am using code from a previous project where I did something similar in creating an array of sounds, so I don't understand why I am getting this error now.
%% SNIPPET OF CODE FROM MAIN FUNCTION
for currentImage = 1:length(allImgs)
filename = allImgs(currentImage) + ".wav";
img = imread(allImgs(currentImage));
[imGray, histMtx, binEdge, notes, songLength] = mus306GenerateNotes(img);
fs = 44100;
time = 1;
values = 0:1/fs:time;
rate = 32768;
for i = 1:songLength
currentNote = notes(i);
singleNote = mus306NoteFinder(currentNote);
[currentOct, ~] = mus306NoteFinder2(currentNote);
octaves(i) = currentOct;
finalNotes(i) = singleNote;
end
secondImg = img;
secondImg(:) = ones(size(secondImg)) * 255;
[r,c,~] = size(img);
for i = 1:songLength
noteLength = durations(randi(durationOption));
octToHear = octaves(i);
note = @(t,freq,oct) sin(linspace(0,2*pi*t*freq*2^oct,round(t*rate)));
% noteSound = sin(linspace(0,2*pi*noteLength*finalNotes(i),...
% round(noteLength*rate)));
noteSound = note(noteLength, finalNotes(i), octToHear);
% ERROR IN LINE BELOW: Unable to perform assignment because the
% size of the left side is 1-by-4096 and the size of the right side
% is 1-by-8192. (i can't figure out how to change the color of this
% to red, apologies)
allNotes(i,:) = noteSound;
sound(noteSound, fs)
pause(0.1)
for row = 1:r
for col = 1:c
if (imGray(row, col) == i)
secondImg(row, col,:) = img(row, col, :);
end
end
end
audiowrite(filename, allNotes, fs);
end
%% CUSTOM FUNCTION MUS306GENERATENOTES.M
function [imGray, histMtx, binEdge, notes, songLength] = mus306GenerateNotes(imgToSee)
audibleMin = 200;
audibleMax = 1000;
imGray = rgb2gray(imgToSee);
[histCount, binEdge] = histcounts(imGray(:), 0:255);
histMtx = [binEdge(1:end-1)', histCount'];
figure(1)
notes = histMtx(:, 2);
songLength = length(notes);
for i = 1:songLength
audibleNote = notes(i);
if ((audibleNote / audibleMin) < 1)
audibleNote = audibleNote * 10;
if ((audibleNote / audibleMax) > 1)
audibleNote = audibleNote / 10;
end
elseif (((audibleNote / audibleMax) > 1))
audibleNote = audibleNote / 10;
if ((audibleNote / audibleMin) < 1)
audibleNote = audibleNote * 10;
end
end
notes(i) = audibleNote;
end
end
  2 Comments
Torsten
Torsten on 28 Nov 2023
And the riddle for us is to find out in which line of your code the error happens ?
Yamini
Yamini on 28 Nov 2023
Apologies, I thought I added in a comment to show where my code is failing. The comment has now been added with the error my system is returning.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 28 Nov 2023
noteLength = durations(randi(durationOption));
A duration is randomly selected
note = @(t,freq,oct) sin(linspace(0,2*pi*t*freq*2^oct,round(t*rate)));
A function is constructed in which the size of the output vector depends on the first parameter.
noteSound = note(noteLength, finalNotes(i), octToHear);
The randomly-chosen duration is passed to the function in the slot the determins the length of the output vector. Therefore, noteSound is a random size.
allNotes(i,:) = noteSound;
The randomly-sized vector is written to a complete row of allNotes.
allNotes was not defined before that statement first executes, so that statement is going to succeed the first iteration. However, the next time that the statement executes with a different random length, the number of columns in noteSound (determined by the duration randomly chosen) is not going to match the number of columns in the existing allNotes array.
audiowrite(filename, allNotes, fs);
audiowrite() treats columns as channels. If everything went well then allNotes is a 2D array with rows according to number of notes, and columns containing the sin information for the note. That is clearly the wrong way around: the time series data for notes must be down columns rather than across columns in order for the time series data to be stored properly. If you were to audiowrite passing in allNotes.' then the individual notes would become different channels. You are writing a .wav file and audiowrite supports up to 1024 channels for .wav files.
I doubt this is what you want to do, but since you are constructing 2D arrays of the sine information, then maybe it is...
  5 Comments
Walter Roberson
Walter Roberson on 28 Nov 2023
Before
for i = 1:songLength
insert
allNotes = cell(songLength,1);
Change
note = @(t,freq,oct) sin(linspace(0,2*pi*t*freq*2^oct,round(t*rate)));
to
note = @(t,freq,oct) sin(linspace(0,2*pi*t*freq*2^oct,round(t*rate))) .';
now change
allNotes(i,:) = noteSound;
to
allNotes{i} = noteSound;
Change
audiowrite(filename, allNotes, fs);
to
audiowrite(filename, cell2mat(allNotes), fs);
Yamini
Yamini on 28 Nov 2023
That worked perfectly!! Thank you so much for all your help!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!