Write a function called mixit

10 views (last 30 days)
Carolina Gaudenzi
Carolina Gaudenzi on 2 Jan 2021
Answered: Rajith on 19 Nov 2023
Write a function called mixit that takes two input arguments. The first is a K-by-N matrix of unit 16 values where N is the number of tracks and k is the number of samples per track, The second input argument is a vector of N double scalars representing the weights of the tracks. The output of the function is a K-element column vector of doubles representing a single-track audio recording obtained by mixing the individual tracks according to the static weights. Note that before any of the processing takes place, the audio data must be converted to standard interval of [-1 1]. That is, unit 0 needs to be mapped to -1, while 65536 becomes +1. The output is expected to be in the same range. If any element of the final mixed audio is outside of this range, the output needs to be scaled. Hint find the maximum of the absolute value of the output vector. If it is greater than 1, you need to divide the entire vector with that value.
This is the code I have written:
function k=mixit(matx, weights)
M=rescale(matx,-1,1); %rescales the matrix between [-1 1]
new=M.*(weights); %creates a new matrix where each element is multiplied by its respective weight
SM=sum(new,2); %sums the elements along the second dimension
k=SM/sum(weights); %does a weighted average of the new track
if abs(max(k))>1
K=rescale(k, -1, 1); %if the absolute value of the max of k is greater than 1 then the output will be rescaled
end
end
When I test it with vector A and [1 1] I get the same output as when I test the function with vector A and [0.5 0.5], and overall, it seems to not be correct code but I have no idea what is wrong. Please help?
  4 Comments
xin yi leow
xin yi leow on 13 Feb 2021
Finally solved it
function track=mixit(org,weights)
%sz=size(weights)
org=double(org);
m=(org./65535).*2.-1
%scaled=weights./sum(weights)
weights=weights.';
track=m*weights;
ma=max(abs(track))
if max(abs(track))>1
track=track/ma;
end
end
Mayank Mohan Arora
Mayank Mohan Arora on 1 Apr 2021
Hey I didnt understand that during scaling, why did you multiply by 2 and subtract 1?
m=(org./65535).*2.-1

Sign in to comment.

Answers (4)

Cris LaPierre
Cris LaPierre on 2 Jan 2021
Edited: Cris LaPierre on 2 Jan 2021
Your example may be too simple.
If you step through the logic of your code, you will see why, in this simplified scenario, your result will always be -1.
When you rescale an array where all values are the same, you are returned a matrix where all values are the left edge of your rescale. Here, that means A become [-1 -1] in both cases.
You next multply your rescaled array by the weights, which result in a new matrix that is the negative of your weights. You then sum them along the 2nd dimension, and then divide them by the sum of weights. Here again, the result is -1 because you have the same numbers on the top and bottom. The numerator is the negative of the denominator.
  3 Comments
Carolina Gaudenzi
Carolina Gaudenzi on 5 Jan 2021
These are three examples given - I get a correct answer in the second (A, [1 0]) and the third example (A, [0.5 0.5]), but when I test my code with the first example (A, [1 1]), I get the same exact vector that I get when I am testing (A, [0.5, 0.5])
Cris LaPierre
Cris LaPierre on 5 Jan 2021
Edited: Cris LaPierre on 5 Jan 2021
I think this is just a function of your approach. Step through your code to see what it is doing.
  1. Scale each column to [-1 1]
  2. Multiply each column by a weight [1 1] or [.5 .5]
  3. Sum each row and divide by the sum of the weights ( 2 or 1). When the weights are 1, the sum in each row is double what it would be when the weights are 0.5. But when the weights are 1, you divide by 2, undoing the doubling. And when the weights are 0.5, you divide by 1, meaining the result is the same as the final results when the weights are both 1..
This pattern holds any time the weights are the same.

Sign in to comment.


Rafael Eduardo Pachas Vega
Below are the steps that I follow.
1) Take the double of the input
2) Scale the modified input ( You have to use this approach: 1 + 2*double(input) ./intmax('uint16'))
3) Use a Matrix multiplication on the scaled input and the transpose of the weights (I do NOT divide by the average weight)
4) Take the max of absolute value of the output
5) If max absolute value of output > 1 divide output by the max absolute value
It works for every questions. And I also get the correct answers for all four examples given.
  1 Comment
xin yi leow
xin yi leow on 3 Feb 2021
i followed this method but got an error when i used intmax('uint16') so i replaced it with 65535. the error is
Error using ./
Integers can only be combined with integers of the same class, or scalar doubles.
Error in mixit (line 4)
m=1 + 2*double(org) ./intmax('uint16');
function track=mixit(org,weights)
org=double(org);
m=1 + 2*double(org) ./65535;
weights=weights.';
track=m*weights;
ma=max(abs(track));
if ma>1
track=track/ma;
end
end

Sign in to comment.


Sandeep Kumar Patel
Sandeep Kumar Patel on 19 Apr 2022
function track=mixit(org,weights)
org=double(org);
m=(org./65535).*2.-1;
weights=weights.';
track=m*weights;
ma=max(abs(track));
if ma>1
track=track/ma;
end
end

Rajith
Rajith on 19 Nov 2023
ans
function s = mixit(S,w)
if size(S,2) ~= length(w)
s = [];
else
w = w(:); % make sure it is a column vector
S = 2 * double(S) / (2^16 - 1) - 1; % scale and shift it to the interval [-1 1]
s = S * w; % matrix multiplication does what we need
if max(abs(s)) > 1 % make sure to stay within range
s = s / max(abs(s));
end
end
end

Categories

Find more on Data Type Identification in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!