A .wav file audio compressor and decompressor written in C and optimized for an ARM-based embedded system. Created for UVic SENG 440: Embedded Systems.
ssh <netlinkID>@seng440.ece.uvic.ca
mkdir /tmp/<your-name>
git clone https://github.com/brettjanz/SENG440.git /tmp/<your-name>
cd /tmp/<your-name>
make
make
: Build main.exe, deploy it to the arm machine, and run it with test.wavmake opt
: Build main_optimized.exe, deploy it to the arm machine, and run it with test.wavmake all
: Build both mains, deploy them to the arm machine, run both with test.wav, and compare their outputsmake clean
: Clean up any files on the arm machine
Global variables will never be placed in a register. We can change this by making variables local to the functions that use them
FILE* input_file
,FILE* output_file
,Wave* wave
, anduint32_t num_samples
have been made local tomain()
uint16_t bytes_per_sample
has been made local toread_wav()
CompressedWave compressedWave
is nowuint16_t* samples
local tomain()
andcompress_data()
Since smaller values occur more often, we can change the order in which we check for different magnitudes in order to speed up execution
get_codeword()
now uses a switch case that checks lower values firstcompressed_magnitude()
now uses a switch case that checks lower values first
We can save on overhead by reducing the amount of times we perform file I/O with fread()
and fwrite()
read_wav()
has been reduced to two read operations, one for the header and one for the sample datawrite_wav()
has been reduced to two write operations, one for the header and one for the sample data
We can save on overhead with simple but often-used functions by inlining their return value instead of making a function call
signum()
has been removed and had all its instances inlinedmagnitude()
has been removed and had all its instances inlinedcompressed_signum()
has been removed and had all its instances inlinedwrite_wav()
has been removed and had all its instances inlined
We can save on overhead by reducing the number of iterations performed in for
loops
compress_data()
now operates in blocks of 8 samples with a switch case handling the modulo remaindercompress_data()
now uses a single-statementwhile
loop instead of a three-statementfor
loopdecompress_data()
now operates in blocks of 8 samples with a switch case handling the modulo remainderdecompress_data()
now uses a single-statementwhile
loop instead of a three-statementfor
loop
Calls to printf()
are slow and unnecessary in an embedded system
- All non-error, non-timer
printf()
calls have been removed