From b5ca6f3f6b16b455e77c67f3aae1d33d2495c393 Mon Sep 17 00:00:00 2001 From: David Westgate Date: Thu, 17 Oct 2024 14:40:10 -0700 Subject: [PATCH] finish clipped --- code/clipped/README.md | 23 ++++++++++++++++++++++- code/clipped/clipped.wav | Bin 0 -> 96044 bytes code/clipped/main.py | 37 +++++++++++++++++++++++++------------ code/clipped/sine.wav | Bin 0 -> 96044 bytes notebook.md | 3 +++ 5 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 code/clipped/clipped.wav create mode 100644 code/clipped/sine.wav diff --git a/code/clipped/README.md b/code/clipped/README.md index 8ac607b..ffed610 100644 --- a/code/clipped/README.md +++ b/code/clipped/README.md @@ -1,4 +1,5 @@ ## Background +Included here is a simple python script used to generate and play some sine waves, specified by the assignment. This script will play a tone, so please ensure your default audio output is properly configured (and not too loud) for your listening enviornment ## Setup Potential libraries needed for debian-based gnu+linux @@ -15,4 +16,24 @@ pip install -r requirnments.txt python3 main.py ``` -## Reflections, Results, Analysis \ No newline at end of file +## View Source +[main.py](./main.py) + +## Access outputs +[sine.wav](./sine.wav) + +[clipped.wav](./clipped.wav) + +## Reflections, Results, Analysis +Overall this portfolio assignment went well. Though I have worked with audio analysis and editing in the past (in a limited capacity), this was my first opportunity to create computer audio at the bit level, and in that regard it was rather exciting and interesting. + +In retrospect, my decision to implement this assignment as a python script seems to have been a good choice. The provided libraries were helpful in providing the raw trigonmetric math and unit casting, without abstracting away the discrete transformation steps needed to get to the result. The calls to `scipy.io.wavfile.write` and `sounddevice.play` were easy and succinct, which allowed me to focus on usage of `numpy` to generate the proper signals with the requested parameters. I did consider implementing this assignment in Rust; this likely would have been fun at the risk of getting caught up in using algorithms from a less-mature library and a more hand-on approach to managing data structures. + +The most challenging part of this assignment was understanding the relationship between time, the wave angle and amplitude to generate the wave. This took some tinkering and iterations to lead to my result. + +My primary technical resources for this assignment were viewing the API documentation for the various libraries +* [Numpy](https://numpy.org/doc/stable/reference/index.html) +* [sounddevice.play](https://python-sounddevice.readthedocs.io/en/0.3.12/api.html#sounddevice.play) +* [scipy.io.wavfile.write](https://docs.scipy.org/doc/scipy/reference/generated/scipy.io.wavfile.write.html) + +I consider this portfolio assignment complete \ No newline at end of file diff --git a/code/clipped/clipped.wav b/code/clipped/clipped.wav new file mode 100644 index 0000000000000000000000000000000000000000..ff96feb1167c32951f7edabe84f909d9ee4173bb GIT binary patch literal 96044 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 XcSRr6XrvFiuB;b*P~q|a``~{8JuG;e literal 0 HcmV?d00001 diff --git a/code/clipped/main.py b/code/clipped/main.py index 6bbb2c6..b269fe8 100644 --- a/code/clipped/main.py +++ b/code/clipped/main.py @@ -1,21 +1,34 @@ -from os.path import dirname, join as pjoin +import string from scipy.io import wavfile as wav import numpy as np -import scipy.io -import sounddevice +import sounddevice as sd import math print("Portfolio assignment 1: Clipped") +print("This program will create (overwrite) sine.wav and clipped.wav per specification\n and will play clipped.wav to the default audio output") -# part 1: building and writing the sine wave -# starting example: https://www.geeksforgeeks.org/numpy-sin-python/ +min_amp = np.iinfo(np.int16).min # = -32767 +max_amp = np.iinfo(np.int16).max # = 32767 -in_array = [0, math.pi / 2, np.pi / 3, np.pi] -print ("Input array : \n", in_array) - -Sin_Values = np.sin(in_array) -print ("\nSine values : \n", Sin_Values) +sample_rate = 48000 # samples/second -# part 2: building and writing clipped wave +def generate(amp: float): + frequency = 440 # cycles/second aka Hz + duration = 1 # seconds + time = np.linspace(0, duration, int(sample_rate * duration), endpoint=False) # array of discrete time values + angle = 2 * np.pi * frequency * time # radians 2π(f * t) + wave = amp * max_amp * np.sin(angle) + return wave.astype(np.int16) -# part 3: playing audio \ No newline at end of file +def write(wave, name: string): + wav.write(name, sample_rate, wave) + +def play(wave): + sd.play(wave, samplerate=sample_rate, blocking=True, loop=False) + +sine = generate(0.25) +clipped = np.clip(generate(0.5), math.floor(min_amp/4.0), math.ceil(max_amp/4.0)) + +write(sine,'sine.wav') +write(clipped,'clipped.wav') +play(clipped) \ No newline at end of file diff --git a/code/clipped/sine.wav b/code/clipped/sine.wav new file mode 100644 index 0000000000000000000000000000000000000000..7d5e7499ecf7e79d6fc17ac4e6c9eedaf4dd30e3 GIT binary patch literal 96044 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 A