-2

I have a matrix (n,16) filled with audio samples of 16 bits each.

So the matrix could look like:

[0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1; 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1]

and so on. How can i actually play this as sound? sound() is using double floating points (from -1 to 1 values). If i could just convert it to those values, I guess it would work, but im not sure. Any suggestions?

timgeb
  • 76,762
  • 20
  • 123
  • 145

1 Answers1

2

@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!

rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • That's exactly what i needed, but my values are in [-32768-32767] range and not from 0 and up, which messes up my negative values (one complimented) for example '1101011100000110' becomes 55046 instead of -10489 with the bin2dec form. So i guess i need to check for the first value in the row each time and use typecast(uint16(bin2dec('the_negative_number')+1),'int16') each time its a negative with a loop. Or is there a smarter way? But thx so far, helped me alot already! – user3752959 Jun 19 '14 at 10:56
  • @user3752959 I can answer this question, but I need to know what format your negative numbers are in. Signed? One's compliment or Two's compliment? We can still do this without a loop – rayryeng Jun 19 '14 at 14:21
  • Signed ones compliment. – user3752959 Jun 19 '14 at 14:34
  • @user3752959 OK, give me a moment to modify my answer. – rayryeng Jun 19 '14 at 14:37
  • @user3752959 - Done. Good luck. – rayryeng Jun 19 '14 at 15:14
  • @user3752959 - Do you require further assistance? – rayryeng Jun 22 '14 at 06:55
  • @user3752959 - Please consider accepting my answer if you require no further help. This signals the SO community that you require no more help. You can do this by going to the top of my post, and clicking on the checkmark that is to the left below the up and down voting buttons – rayryeng Jun 25 '14 at 22:08