Skip to content

Commit 6f4a43d

Browse files
committed
Clean commit of project files
0 parents  commit 6f4a43d

File tree

85 files changed

+5513
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+5513
-0
lines changed

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Sevag Hanssian
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Real-Time-HPSS
2+
3+
This repository contains a real-time implementation of the median-filtering HPSS algorithm [[1]](http://dafx10.iem.at/papers/DerryFitzGerald_DAFx10_P15.pdf), [[2]](https://www.audiolabs-erlangen.de/content/05-fau/assistant/00-driedger/01-publications/2014_DriedgerMuellerDisch_ExtensionsHPSeparation_ISMIR.pdf).
4+
5+
The original implementation uses the STFT/spectrogram of the audio signal to create harmonic and percussive masks, which are then applied to the STFT. The ISTFT is taken to create the separated harmonic and percussive audio signals. By combining the STFT and ISTFT loops and creating a sliding STFT, the separation can be done in real-time:
6+
7+
<img src="./images/rt_hpss_diagram.png" width=700>
8+
9+
### MATLAB implementation
10+
11+
There's a [demo script](./matlab/HPSSMicrophone.m) which performs live, real-time HPSS on a microphone input stream (watch out for feedback - you should probably have your output and input devices in different rooms). PDFs of the report and presentation (built from the latex sources in this repo) are distributed as well on the [releases page](https://github.com/sevagh/Real-Time-HPSS/releases). The spectrograms below were created with [HPSSRtWav.m](./matlab/HPSSRtWav.m), a chunked processing of wav files to demonstrate the validity of real-time HPSS without the complications of microphone recordings.
12+
13+
Mixed spectrogram:
14+
15+
<img src="./images/mixedspecgram.png" width=512>
16+
17+
Real-time harmonic separation:
18+
19+
<img src="./images/harm_realtime.png" width=512>
20+
21+
Real-time percussive separation:
22+
23+
<img src="./images/perc_realtime.png" width=512>
24+
25+
### Python demo
26+
27+
The file [chunked_wav_example.py](./chunked_wav_example.py) uses the `hpss_rt` package in the [python subdirectory](./python):
28+
29+
```python
30+
fs, x = scipy.io.wavfile.read("mixed.wav")
31+
hpss = HPSSRT(fs)
32+
33+
h = numpy.ndarray(shape=x.shape)
34+
p = numpy.ndarray(shape=x.shape)
35+
36+
x_ptr = 0
37+
while x_ptr < len(x):
38+
if len(x[x_ptr : x_ptr + hpss.hop]) != hpss.hop:
39+
# skip uneven/non-hop-sized last chunk
40+
break
41+
h_, p_ = hpss.process_next_hop(x[x_ptr : x_ptr + hpss.hop])
42+
h[x_ptr : x_ptr + hpss.hop] = h_
43+
p[x_ptr : x_ptr + hpss.hop] = p_
44+
x_ptr += hpss.hop
45+
46+
scipy.io.wavfile.write("h_rt_sep_python.wav", fs, h)
47+
scipy.io.wavfile.write("p_rt_sep_python.wav", fs, p)
48+
49+
fs, xm = scipy.io.wavfile.read("mixed.wav")
50+
fs, xh = scipy.io.wavfile.read("h_rt_sep_python.wav")
51+
fs, xp = scipy.io.wavfile.read("p_rt_sep_python.wav")
52+
_, _, _, im = plt.specgram(xm, Fs=fs, NFFT=1024, noverlap=256)
53+
plt.show()
54+
_, _, _, im = plt.specgram(xh, Fs=fs, NFFT=1024, noverlap=256)
55+
plt.show()
56+
_, _, _, im = plt.specgram(xp, Fs=fs, NFFT=1024, noverlap=256)
57+
plt.show()
58+
```
59+
60+
Mixed spectrogram:
61+
62+
<img src="./images/mixed_specgram_matplotlib.png" width=512>
63+
64+
Real-time harmonic separation:
65+
66+
<img src="./images/harm_specgram_matplotlib.png" width=512>
67+
68+
Real-time percussive separation:
69+
70+
<img src="./images/perc_specgram_matplotlib.png" width=512>
71+
72+
### Project files
73+
74+
* audio - audio clips used throughout the report and presentation to generate results, plots
75+
* images - plots, etc. for the report and presentation
76+
* latex - latex files for the report and presentation PDFs
77+
* matlab - matlab scripts
78+
* HPSS.m - median-filtering HPSS (with both the 2010 and 2014 techniques)
79+
* HPSSWav.m - a file that loads a wav file and applies HPSS.m
80+
* HPSSMicrophone.m - a real-time implementation that separates and outputs percussive or harmonic separations of the microphone input in real-time
81+
* HPSSRtWav.m - a modification of HPSSMicrophone.m to test the real-time implementation with wav files
82+
* python - python library + class, `from hpss_rt import HPSSRT`
83+
84+
### About this project
85+
86+
Real-Time-HPSS is presented as my final project for MUMT 501, Winter 2020.

audio/drum.wav

316 KB
Binary file not shown.

audio/harm_driedger_nonrealtime.wav

315 KB
Binary file not shown.

audio/harm_fitzgerald_nonrealtime.wav

315 KB
Binary file not shown.

audio/harm_rt.wav

316 KB
Binary file not shown.

audio/mestis_el_mestizo_shorter.wav

938 KB
Binary file not shown.

audio/mestis_harm_offline_shorter.wav

938 KB
Binary file not shown.

audio/mestis_harm_rt_shorter.wav

938 KB
Binary file not shown.

audio/mestis_perc_offline_shorter.wav

938 KB
Binary file not shown.

audio/mestis_perc_rt_shorter.wav

938 KB
Binary file not shown.

audio/mixed.wav

316 KB
Binary file not shown.

audio/perc_driedger_nonrealtime.wav

315 KB
Binary file not shown.

audio/perc_fitzgerald_nonrealtime.wav

315 KB
Binary file not shown.

audio/perc_rt.wav

316 KB
Binary file not shown.

audio/viola.wav

631 KB
Binary file not shown.

chunked_wav_example.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env python3.7
2+
3+
from hpss_rt import HPSSRT
4+
import sys
5+
import time
6+
import numpy
7+
import scipy
8+
import scipy.io.wavfile
9+
import matplotlib.pyplot as plt
10+
11+
12+
if __name__ == "__main__":
13+
infile = ""
14+
try:
15+
infile = sys.argv[1]
16+
except:
17+
print("usage: {0} /path/to/wav/file", file=sys.stderr)
18+
sys.exit(1)
19+
20+
fs, x = scipy.io.wavfile.read(infile)
21+
hpss = HPSSRT(fs)
22+
23+
h = numpy.ndarray(shape=x.shape)
24+
p = numpy.ndarray(shape=x.shape)
25+
26+
x_ptr = 0
27+
total = 0
28+
while x_ptr < len(x):
29+
if len(x[x_ptr : x_ptr + hpss.hop]) != hpss.hop:
30+
# skip uneven/non-hop-sized last chunk
31+
break
32+
start = time.time()
33+
h_, p_ = hpss.process_next_hop(x[x_ptr : x_ptr + hpss.hop])
34+
total += time.time() - start
35+
h[x_ptr : x_ptr + hpss.hop] = h_
36+
p[x_ptr : x_ptr + hpss.hop] = p_
37+
x_ptr += hpss.hop
38+
39+
total /= x_ptr / hpss.hop
40+
print("average time per loop iter: {0}".format(total))
41+
42+
scipy.io.wavfile.write("h_rt_sep_python.wav", fs, h)
43+
scipy.io.wavfile.write("p_rt_sep_python.wav", fs, p)
44+
45+
fs, xm = scipy.io.wavfile.read(infile)
46+
fs, xh = scipy.io.wavfile.read("h_rt_sep_python.wav")
47+
fs, xp = scipy.io.wavfile.read("p_rt_sep_python.wav")
48+
_, _, _, im = plt.specgram(xm, Fs=fs, NFFT=1024, noverlap=256)
49+
plt.show()
50+
_, _, _, im = plt.specgram(xh, Fs=fs, NFFT=1024, noverlap=256)
51+
plt.show()
52+
_, _, _, im = plt.specgram(xp, Fs=fs, NFFT=1024, noverlap=256)
53+
plt.show()

images/drum_waveform.png

71.2 KB
Loading

images/drumspecgram.png

575 KB
Loading

images/drumspecgram_orig.png

531 KB
Loading

images/hann_taper_window.png

61.7 KB
Loading

images/harm_3way.png

320 KB
Loading

images/harm_binary.png

404 KB
Loading

images/harm_driedger_cmp.png

209 KB
Loading

images/harm_driedger_waveform.png

68.5 KB
Loading

images/harm_fitzgerald_cmp.png

198 KB
Loading

images/harm_fitzgerald_waveform.png

73.2 KB
Loading

images/harm_realtime.png

600 KB
Loading

images/harm_realtime_cmp.png

197 KB
Loading

images/harm_soft.png

575 KB
Loading

images/harm_specgram_matplotlib.png

356 KB
Loading

images/hpss_causality.png

640 KB
Loading

0 commit comments

Comments
 (0)