@AnderBiguri pretty much nailed it. Take your array, convert it to signed double, normalize and play it.
As you have a n x 16
matrix, where each row is a sample and each column is a bit for that number, first we need to convert that matrix into double format. We can use bin2dec
to help us to do that. However, bin2dec
takes in a string
. As such, we can convert our matrix into a string array like so. Let's assume that inSound
contains your sound matrix that you specified before.
I will also assume that your bits are in Big-Endian format, so the most significant bit is the left most bit, following down to the right most bit.
According to your comments, the numbers are signed 1's compliment. This means that should the most significant bit be 1, we simply invert the entire number. As such, we can figure out which rows are negative by checking the entire first column to see if there is a 1
or 0
. We find the rows with 1
and simply take 1
and subtract every single element in the array. As such:
checkSign = inSound(:,1) == 1;
inSound(checkSign,:) = 1 - inSound(checkSign,1);
Therefore, when we convert our number to decimal, we simply find those rows again that should be negative and simply negate them. Let's convert our numbers first.
inSoundString = char(inSound + '0');
char
converts each number in a matrix or vector into its string representation, assuming that the input into char
is an ASCII code. As such, when we add with 0
, we are adding each number in inSound
with the numerical ASCII code that is representative of what 0
is in ASCII. This is our baseline to start with. After that, inSound
will add either 0
or 1
to this numerical code so that when we convert this whole matrix into a string, we will finally get the string representation of those numbers.
Now convert the binary strings into actual numbers:
outSoundDec = bin2dec(inSoundString);
This will take each row and convert it into its decimal equivalent. Now, if your bits are in Little-Endian, you can use swapbytes
to flip the bits so that you can transform the bits to Big-Endian before proceeding. Now that we have converted our numbers, we need to negate those rows that were supposed to be negative.
As such:
outSoundDec(checkSign) = -outSoundDec(checkSign);
Now we need to normalize this so that the range is between -1
to 1
. Given that you have specified that the range is between [-32768, 32767]
, we simply divide all of our numbers by 32768
. Therefore:
outSound = outSoundDec / 32768;
The above code will now normalize your signal so that it goes from -1
to 1
. You can use sound(outSound, Fs);
to play your sound where Fs
is the sampling frequency your signal was obtained at.
Good luck!