# ICA HW4
> [name=0516009 吳宗達、0611097曾力揚、0616015 劉姿利]
## File Structure
```a
.
├── imgs
│ ├── given-wav-filters.png
│ ├── given-wav.png
│ ├── sin0.png
│ ├── sin1-filters.png
│ ├── sin1.png
│ ├── sin2.png
│ ├── white-noise-filters.png
│ └── white-noise.png
├── pdf
│ └── hw4_0516009_0611097_0616015.pdf
├── README.md
└── src
├── Filter.py
├── hw4_0516009_0611097_0616015.py
├── Plot.py
├── Signal.py
└── wavfiles
├── n1n.wav
├── noise.wav
├── sin0.wav
├── sin1.wav
├── sin2.wav
└── ul1.wav
```
## Execution
```bash
cd src
python3 hw4_0516009_0611097_0616015.py
```
## Code Architecture
### Signal Module (`Signal.py`)
#### Read/Write
```python
def readWav(filename):
```
Read .wav file as wave tuple.
Return: a wave tuple
```python
def writeWav(wav, filename):
```
Write .wav file as wave tuple.
#### White Noise
```python
def genWhiteNoise(length=20, sample_rate=44100):
```
Generate white noise as wave tuple.
Return: a wave tuple
#### Sum of Sinusoids
```python
def genSumOfSinusoids(harmonic, length=20, sample_rate=44100, f=440):
```
Generate sum of sinusoids as wave tuple.
Return: a wave tuple
```python
for n in range(len(harmonic)):
y += harmonic[n] * np.sin((n+1) * 2 * np.pi * f * x)
```

The implementation of computing sum of sinusoids.
Return: a wave tuple
### Filter Module (`Filter.py`)
```python
def lowPassFilter(wav, numtaps=10000, cutoff=0.5, fs=None):
def highPassFilter(wav, numtaps=10001, cutoff=0.5, fs=None):
```
Use scipy.signal.firwin to design FIR low/high pass filter, and implement it on a wave tuple.
Return: a wave tuple after implementing the filter
### Plot Module (`Plot.py`)
```python
def getFreqDomain(wav):
```
Get the frequency domain of a wave tuple.
Return: x, y of the frequency domain on the plot
```python
def plotWav(wav, title, time_xlim=None, freq_xlim=None):
```
Visualize the signals both in time domain and frequency domain.
```python
def plotWavWithFilters(wav, wav_high, wav_low, title, time_xlim=None, freq_xlim=None):
```
Plot three wave tuples (original, with low pass filter, with high pass filter) on to one plot both in time domain and frequency domain.
### Main (`main.py`)
This is where we demo our results.
## Steps
### White noise
1. generate wave tuples
```python
noise = Signal.genWhiteNoise()
```
2. write the wave tuple as .wav file
```python
Signal.writeWav(noise, 'wavfiles/noise.wav')
```
3. plot the analyzing result

4. with filters

### Sum of sinusoids
1. generate wave tuples
```python
sin0 = Signal.genSumOfSinusoids([1.0, 0.0, 1.0])
sin1 = Signal.genSumOfSinusoids([1.0, 0.5, 0.33, 0.25, 0.2, 0.1667, 0.14])
sin2 = Signal.genSumOfSinusoids([1.0, 0.0, 0.33, 0.0, 0.2, 0.0, 0.14])
```
2. write the wave tuples as .wav files
```python
Signal.writeWav(sin0, 'wavfiles/sin0.wav')
Signal.writeWav(sin1, 'wavfiles/sin1.wav')
Signal.writeWav(sin2, 'wavfiles/sin2.wav')
```
3. plot the analyzing results
- sin0

- sin1

- sin2

4. with filters (on sin1)

### Given .wav file from disk
1. Read the .wav file on the disk as wave tuple
```python
wav = Signal.readWav('wavfiles/ul1.wav')
```
2. Plot the analyzing results

3. with filters
