This lab was quite interesting. Before starting the lab, we discussed how sound is analyzed and how to scale the sound input programmatically. The way that sound is analyzed is nothing special. The sound input is represented through integers and floats (decimal numbers) and any analysis is done is just by analyzing the numbers. And to raise or lower the volume is nothing more than just performing arithmetic operations on each number in the sound sample. And so this was the goal of the lab. But the goal had a catch. The most simplest solution, or naive, was just loop through all the numbers and perform the operation. But this was slow and not the efficient solution because imagine doing this on a mobile phone. This would destroy the battery as every time the user raised or lowered the volume, the CPU would perform this looping process. So our challenge was to come up with a more efficient way of doing this.
In the lab, we were given a sound sample which was represented by just random numbers between -65,536 and 65536. Why between those odd numbers? Well because we were working with an array of type 16-bit floats. So after the numbers were generated, we perform the operation of “raising/lowering” the volume. We were also given 2 algorithms to try out and see which one would was the better of the two. The first algorithm consisted of having a table of pre-computed table with that contained all the values between -65,536 and 65.536 multiplied by the scale factor – 0.75 in our case. Then when computing the output array, or sample with the volume scaled applied, you would just have to look up the corresponding value of the sample in the look-up table and use that to represent that specific sample in the output array. So to put it into pseudo code, calculate the pre-computed table in which each value of the array is the index * volume factor. Then loop through the sample array, store the value of the current iteration, and use that to look up the corresponding scaled value in the pre-computed table. And then store the “looked-up” value in the output array. This was one solution that my team was able to complete. Unfortunately as with everything, we encountered a bug that we spent some time trying to figure out but couldn’t. And soon enough it was the end of class. We’re still working on the lab and will have the results soon. I’ll discuss the other algorithm which is simpler to understand this one.
The other algorithm was just to bit-shift everything to the right with the number of places depending on the volume factor. We didn’t get time as a group or individually to try out and discuss the results of this algorithm so I cannot say much. Now if i were to predict which would be the better solution of the two, I would say definitely bit-shifting. One of the reasons why I say this is because multiplication is slower than bit-shifting. And why is it slower? Because the CPU has to compute the value rather than just shift the bits around in memory which is what bit-shifting, as the name applies, literally is. In terms of memory usage, I would predict that bit-shifting also wins this one because the other solution would require you to store the look-up table somewhere in memory to refer to it. Although since we were working with only 16-bit numbers, the maximum number is 65, 536 and well, that could easily be stored in registers as most modern PCs have capabilities of storing 64k bits into registers. So it’s hard to say anything without actually bench-marking but I would still say bit-shifting wins since less computation is required.