Computer Science Department |
CSCI 135 |
You are tasked with completing a command line utility that lets users mix and mash audio files. (Yes, this means you will have to run your code from the command line.) Using simple starting sounds, users can create a masterpiece of audacious audio. Using the utility, users can cut out sections of sound, add leading and trailing silence, add echoes, merge sounds, reverse sounds, and loop sounds. Luckily a previous developer has already implemented the calling code and a handful of the utility's effects (play, stats, and gain). Your task is to complete functions for the reverse, loop, merge, echo, cut and pad audio effects. Here is an example mix created from this set of commands. |
To start with, download the audio.zip file and unzip it to your program directory.
This file contains the existing source code AudioEffects.py as well as a selection of audio files for your testing pleasure.
You will be using StdAudio.py to handle the loading and playback of audio.
StdAudio provides access to the audio samples in a WAV format audio file via a list of floating point numbers. To use StdAudio, it is imported into the program - this has been done or you.
All your audio manipulating functions will operate by manipulating and returning lists.
You should not change the list passed as a parameter to your functions.
Rather you should create a new list, fill it with values, and return it from each function (for an example see the audioGain() function).
Each audio sample in a file is representing by a float value, typically between -1.0 and +1.0.
Values outside this range are clipped to -1.0 or +1.0 during playback.
The bigger the absolute value of the float value, the louder the sound is at that point in the file.
All the provided audio files are recorded at 44100 samples per second so as to work with StdAudio.
If want to try your program with your own audio files, make sure they are WAV format, recorded at 44100 samples per second, 16-bit, mono, signed format.
If you want to convert files in a different format, various programs such as GoldWave can do this.
The provided AudioEffects.py file is partially completed.
You need to fill in the function bodies for audioReverse(), audioLoop(), audioMerge(), and audioCut(). You need to add all of the audioPad() and audioEcho() functions as well as the calls to audioPad and audioEcho in the main part of the program.
Before each function, you'll find a detailed comment describing what the function does, its input parameters (or arguments), and its return values.
Users of your utility may not always make the most sensible requests (e.g. asking to loop an audio clip -43 times).
Your program should defend itself against such silly requests and not crash.
In the case of bad input to your function, simply return an appropriate failure value as specified by the method comment (typically an empty list).
The first example usage below shows the command line arguments taken by the program.
The first argument is always the filename of the WAV file.
The second argument is always one of the effect names given as a string (e.g. "play", "stats", "reverse", "gain").
After this, there are zero or more additional arguments depending on the type of effect.
How do I convert from a time in seconds to a sample index?
All the audio in this assignment is sampled at 44100 samples per second (declared as a constant SAMPLING_RATE in AudioEffects.py).
If you multiply the time in seconds by SAMPLING_RATE you will get the sample number.
In our solution, we dropped the decimal portion by changing this calculated value to an int.
In general, you should avoid putting "magic numbers" such as 44100 in your code and instead use a declared constant such as SAMPLING_RATE.
This is better style as the name tells the reader what it means and also makes it easy to change the value everywhere by one simple change.
Reverse:% python AudioEffects.py AudioEffects <infile> <effect> [options] Effects: play - play the file stats - print some stats about the audio reverse <out file> - reverse an audio file gain <factor> <out file> - change the volume by given factor loop <times> <out file> - loop audio given number of times merge <infile2> <out file> - merge two audio files together cut <start> <end> <out file> - clip audio from [start, end] seconds pad <start> <end> <out file> - add silence to start and/or end echo <secs> <factor> <out file> - add an echo to audio Supports only 44.1 kHz mono 16-bit signed WAV audio files.
Loop:% python AudioEffects.py piano reverse piano_reverse Effect: reverse Wrote 226800 samples to piano_reverse % python AudioEffects.py piano_reverse stats Effect: stats Samples : 226800 Length (s) : 5.142857142857143 Average level : 4.417823369309006e-05 Max level : 0.43443098239082 Below 1%% max (%%) : 3.11331569664903 Below 5%% max (%%) : 15.427689594356261
Merge:% python AudioEffects.py scratch loop 4 scratch_loop4 Effect: loop Wrote 282036 samples to scratch_loop4 % python AudioEffects.py scratch_loop4 stats Effect: stats Samples : 282036 Length (s) : 6.3953741496598635 Average level : -0.0016209964588888178 Max level : 1.0 Below 1%% max (%%) : 34.22399977307861 Below 5%% max (%%) : 59.749819172020594 % python AudioEffects.py scratch loop -43 scratch_loop-43 Effect: loop
Cut:% python AudioEffects.py cow merge chimes cow_chimes Effect: merge Wrote 275015 samples to cow_chimes % python AudioEffects.py cow_chimes stats Effect: stats Samples : 275015 Length (s) : 6.236167800453515 Average level : -7.51552211158154e-05 Max level : 0.3882869960631123 Below 1%% max (%%) : 28.735523516899082 Below 5%% max (%%) : 65.23244186680726 % python AudioEffects.py beatbox merge harp beatbox_harp Effect: merge Wrote 89491 samples to beatbox_harp Effect: stats Samples : 89491 Length (s) : 2.0292743764172334 Average level : 0.000768471967108367 Max level : 0.5091708120975371 Below 1%% max (%%) : 25.547820451218556 Below 5%% max (%%) : 63.73043099306075
Pad:% python AudioEffects.py dialup cut 4.0 5.0 dialup_cut4-5 Effect: cut Wrote 44100 samples to dialup_cut4-5 % python AudioEffects.py dialup_cut4-5 stats Effect: stats Samples : 44100 Length (s) : 1.0 Average level : 0.017000534316132934 Max level : 0.3241981261635182 Below 1%% max (%%) : 3.2698412698412698 Below 5%% max (%%) : 24.467120181405896 % python AudioEffects.py dialup cut 4.0 50.0 dialup_cut4-50 Effect: cut % python AudioEffects.py dialup cut 5.0 4.0 dialup_cut5-4 Effect: cut
Echo:% python AudioEffects.py buzzer pad 1.0 2.0 buzzer_pad1-2 Effect: pad Wrote 216969 samples to buzzer_pad1-2 % python AudioEffects.py buzzer_pad1-2 stats Effect: stats Samples : 216969 Length (s) : 4.919931972789116 Average level : -4.4007789406573295e-06 Max level : 0.9979247413556321 Below 1%% max (%%) : 62.10472463808194 Below 5%% max (%%) : 66.3643193267241 % python AudioEffects.py buzzer pad -10.0 -20.0 buzzer_pad-10-20 Effect: pad
% python AudioEffects.py singer echo 0.5 0.6 singer_echo_0.5_0.6 Effect: echo Wrote 680597 samples to singer_echo_0.5_0.6 % python AudioEffects singer_echo_0.5_0.6 stats Effect: stats Samples : 680597 Length (s) : 15.433038548752835 Average level : -1.4898577816164841e-05 Max level : 0.9656666768395031 Below 1%% max (%%) : 32.031290176124784 Below 5%% max (%%) : 54.44132136932722
Grading Each function is worth up to 4 points, with an additional 6 points for turning in a program that compiles and runs and has an appropriate header comment, for a total of 30 points, as shown in the following criteria:
Grade Item | Audio Effects | Points Earned |
---|---|---|
Program Compiles and Runs | 4 | |
Header Comment | 2 | |
Reverse Method Runs Correctly | 4 | Loop Method Runs Correctly | 4 | Merge Method Runs Correctly | 4 | Cut Method Runs Correctly | 4 | Pad Method Runs Correctly | 4 | Echo Method Runs Correctly | 4 |
Page last updated: August 16, 2021