Coverage for tests\test.py: 100%
98 statements
« prev ^ index » next coverage.py v7.5.3, created at 2024-06-08 17:00 +0100
« prev ^ index » next coverage.py v7.5.3, created at 2024-06-08 17:00 +0100
1"""
2Audio tone files from https://www.mediacollege.com/audio/tone/download/
3"""
5import os
6import sys
8sys.path.insert(
9 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src"))
10)
12import pathlib
13import unittest
15import numpy as np
16import soundfile
17from simplestretch import speedup_audio, stretch_audio
20class TestAudioFunctions(unittest.TestCase):
21 def setUp(self):
22 # Create a simple audio signal for testing
23 self.sine_samplerate = 44100
24 duration = 2 # seconds
25 t = np.linspace(
26 0, duration, int(self.sine_samplerate * duration), endpoint=False
27 )
28 self.sine_audio = 0.5 * np.sin(
29 2 * np.pi * 440 * t
30 ) # Generate a 440 Hz sine wave
33 def test_stretch_audio_raw(self):
34 factor = 2
36 stretched_audio, stretched_samplerate = stretch_audio(
37 audio=self.sine_audio, factor=factor, samplerate=self.sine_samplerate
38 )
40 self.assertEqual(self.sine_audio.all(), stretched_audio.all())
42 self.assertEqual(round(self.sine_samplerate / factor), stretched_samplerate)
45 def test_speedup_audio_raw(self):
46 factor = 2
48 spedup_audio, spedup_samplerate = speedup_audio(
49 audio=self.sine_audio, factor=factor, samplerate=self.sine_samplerate
50 )
52 self.assertEqual(self.sine_audio.all(), spedup_audio.all())
54 self.assertEqual(round(self.sine_samplerate / (1 / factor)), spedup_samplerate)
57 def test_stretch_audio_file_wav(self):
58 factor = 2
59 file = "tests/sample_files/440hz.wav"
61 audio, samplerate = soundfile.read(file)
63 stretched_audio, stretched_samplerate = stretch_audio(audio=file, factor=factor)
65 self.assertEqual(audio.all(), stretched_audio.all())
67 self.assertEqual(round(samplerate / factor), stretched_samplerate)
70 def test_stretch_audio_file_mp3(self):
71 factor = 2
72 file = "tests/sample_files/440hz.mp3"
74 audio, samplerate = soundfile.read(file)
76 stretched_audio, stretched_samplerate = stretch_audio(audio=file, factor=factor)
78 self.assertEqual(audio.all(), stretched_audio.all())
80 self.assertEqual(round(samplerate / factor), stretched_samplerate)
83 def test_speedup_audio_file_wav(self):
84 factor = 2
85 file = "tests/sample_files/440hz.wav"
87 audio, samplerate = soundfile.read(file)
89 spedup_audio, spedup_samplerate = speedup_audio(audio=file, factor=factor)
91 self.assertEqual(audio.all(), spedup_audio.all())
93 self.assertEqual(round(samplerate / (1 / factor)), spedup_samplerate)
96 def test_speedup_audio_file_mp3(self):
97 factor = 2
98 file = "tests/sample_files/440hz.wav"
100 audio, samplerate = soundfile.read(file)
102 spedup_audio, spedup_samplerate = speedup_audio(audio=file, factor=factor)
104 self.assertEqual(audio.all(), spedup_audio.all())
106 self.assertEqual(round(samplerate / (1 / factor)), spedup_samplerate)
109 def test_stretch_save_audio_file_wav(self):
110 factor = 2
111 out_file = "tests/test_files/stretch_save_test.wav"
113 stretch_audio(
114 audio=self.sine_audio,
115 factor=factor,
116 output=out_file,
117 samplerate=self.sine_samplerate,
118 )
120 # Assert the file exists
121 path = pathlib.Path(out_file)
122 self.assertTrue(path.is_file())
124 # Assert the file contents are correct
125 out_audio, out_samplerate = soundfile.read(out_file)
127 self.assertEqual(self.sine_audio.all(), out_audio.all())
129 self.assertEqual(round(self.sine_samplerate / factor), out_samplerate)
131 def test_speedup_save_audio_file(self):
132 factor = 2
133 out_file = "tests/test_files/speedup_save_test.wav"
135 speedup_audio(
136 audio=self.sine_audio,
137 factor=factor,
138 output=out_file,
139 samplerate=self.sine_samplerate,
140 )
142 # Assert the file exists
143 path = pathlib.Path(out_file)
144 self.assertTrue(path.is_file())
146 # Assert the file contents are correct
147 out_audio, out_samplerate = soundfile.read(out_file)
149 self.assertEqual(self.sine_audio.all(), out_audio.all())
151 self.assertEqual(round(self.sine_samplerate / (1 / factor)), out_samplerate)
154 def test_stretch_invalid_audio_type(self):
155 factor = 2
157 # Pass an invalid audio data type
158 self.assertRaises(TypeError, lambda:stretch_audio(audio=None, factor=factor, samplerate=self.sine_samplerate))
161 def test_stretch_invalid_factor_zero(self):
162 self.assertRaises(ValueError, lambda:stretch_audio(audio=self.sine_audio, factor=0, samplerate=self.sine_samplerate))
165 def test_stretch_invalid_factor_negative(self):
166 self.assertRaises(ValueError, lambda:stretch_audio(audio=self.sine_audio, factor=-1, samplerate=self.sine_samplerate))
169 def test_stretch_raw_data_no_samplerate(self):
170 factor = 2
172 self.assertRaises(TypeError, lambda:stretch_audio(audio=self.sine_audio, factor=factor))
174 def test_stretch_raw_data_invalid_samplerate(self):
175 factor = 2
177 self.assertRaises(TypeError, lambda:stretch_audio(audio=self.sine_audio, factor=factor, samplerate=""))
180 def test_stretch_raw_data_float_samplerate(self):
181 factor = 2
183 stretched_audio, stretched_samplerate = stretch_audio(
184 audio=self.sine_audio, factor=factor, samplerate=float(self.sine_samplerate)
185 )
187 self.assertEqual(self.sine_audio.all(), stretched_audio.all())
189 self.assertEqual(round(self.sine_samplerate / factor), stretched_samplerate)
192 def test_stretch_save_invalid_mp3_samplerate(self):
193 factor = 0.5
195 out_file = "tests/test_files/stretch_invalid_mp3_save_test.mp3"
197 self.assertRaises(soundfile.LibsndfileError, lambda:stretch_audio(audio=self.sine_audio, factor=factor, output=out_file, samplerate=self.sine_samplerate))
199 # Assert file was deleted
200 self.assertFalse(pathlib.Path(out_file).exists())
203 def test_speedup_invalid_factor_zero(self):
204 self.assertRaises(ValueError, lambda:speedup_audio(audio=self.sine_audio, factor=0, samplerate=self.sine_samplerate))
207 def test_speedup_invalid_factor_negative(self):
208 self.assertRaises(ValueError, lambda:speedup_audio(audio=self.sine_audio, factor=-1, samplerate=self.sine_samplerate))
213if __name__ == "__main__":
214 unittest.main() # pragma: no cover