Montana Tech of The University of Montana
Computer Science Department

CSCI 135
Fundamentals of Computer Science I
Fall 2019



ASSIGNMENT 6

In this assignment, you will will be implementing a variety of functions. You will also get additional practice creating and using lists.

Get STDIO.PY here!!!


Audio Effects
You are tasked with completing a command line utility that lets users mix and mash audio files. 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 input 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.


Example usage:
% 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.
Reverse:
% 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
Loop:
% 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
Merge:
% 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
Cut:
% 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
Pad:
% 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
Echo:
% 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

Extra-credit. Using only the audio provided in the audio.zip file, create an audio mashup. Submit your single best artistic creation along with the step-by-step commands used to generate it to the Extra Credit dropbox at the top of the Moodle page. You may add additional effects to AudioEffects if it aids in the creation of your masterpiece. There are many additional sound effects you could add such as fading in/out, adjusting pitch, averaging samples, adding random noise, etc.

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



Submission. Submit your program AudioEffects.py using the Moodle dropbox for Assignment 6. Be sure your submitted file has the required header with your name and a description of the program. Also make sure you follow the guidelines for good programming style.

Page last updated: October 16, 2019