def test_metadata_set(self): self.toRemove("file.ogg") w = wavefile.WaveWriter("file.ogg", format=wavefile.Format.OGG | wavefile.Format.VORBIS) w.metadata.title = 'mytitle' w.metadata.copyright = 'mycopyright' w.metadata.software = 'mysoftware' w.metadata.artist = 'myartist' w.metadata.comment = 'mycomment' w.metadata.date = 'mydate' w.metadata.album = 'myalbum' w.metadata.license = 'mylicense' w.metadata.tracknumber = '77' w.metadata.genre = 'mygenre' w.close() r = wavefile.WaveReader("file.ogg") self.assertEqual("mytitle", r.metadata.title) self.assertEqual("mycopyright", r.metadata.copyright) self.assertEqual("mysoftware ({0})".format(self.sfversion), r.metadata.software) self.assertEqual("myartist", r.metadata.artist) self.assertEqual("mycomment", r.metadata.comment) self.assertEqual("mydate", r.metadata.date) self.assertEqual("myalbum", r.metadata.album) self.assertEqual("mylicense", r.metadata.license) if self.sfversion != 'libsndfile-1.0.25': self.assertEqual("77", r.metadata.tracknumber) self.assertEqual("mygenre", r.metadata.genre) r.close()
def test_metadata_iter(self): self.toRemove("file.ogg") w = wavefile.WaveWriter("file.ogg", format=wavefile.Format.OGG | wavefile.Format.VORBIS) w.metadata.title = 'mytitle' w.metadata.copyright = 'mycopyright' w.metadata.software = 'mysoftware' w.metadata.artist = 'myartist' w.metadata.comment = 'mycomment' w.metadata.date = 'mydate' w.metadata.album = 'myalbum' w.metadata.license = 'mylicense' w.metadata.tracknumber = '77' w.metadata.genre = 'mygenre' w.close() r = wavefile.WaveReader("file.ogg") strings = dict(r.metadata) expected = dict( title='mytitle', copyright='mycopyright', software='mysoftware ({0})'.format(self.sfversion), artist='myartist', comment='mycomment', date='mydate', album='myalbum', license='mylicense', ) if self.sfversion != 'libsndfile-1.0.25': expected.update( tracknumber='77', genre='mygenre', ) self.assertEqual(strings, expected) r.close()
def test_samplerate_byDefault(self): self.toRemove("file.wav") w = wavefile.WaveWriter("file.wav") w.close() r = wavefile.WaveReader("file.wav") self.assertEqual(44100, r.samplerate) r.close()
def test_sampelrate_set(self): self.toRemove("file.wav") w = wavefile.WaveWriter("file.wav", samplerate=22050) w.close() r = wavefile.WaveReader("file.wav") self.assertEqual(22050, r.samplerate) r.close()
def test_format_byDefault(self): self.toRemove("file.wav") w = wavefile.WaveWriter("file.wav") w.close() r = wavefile.WaveReader("file.wav") self.assertEqual(hex(wavefile.Format.WAV | wavefile.Format.FLOAT | 0), hex(r.format))
def test_channels_set(self): self.toRemove("file.wav") w = wavefile.WaveWriter("file.wav", channels=4) w.close() r = wavefile.WaveReader("file.wav") self.assertEqual(4, r.channels) r.close()
def test_writter_withWrongPath(self): try: w = wavefile.WaveWriter("/badpath/file.wav") self.fail("Exception expected") except IOError as e: self.assertEqual( ("Error opening '/badpath/file.wav': System error.", ), e.args)
def test_format_whenOgg(self): self.toRemove("file.ogg") w = wavefile.WaveWriter("file.ogg", format=wavefile.Format.OGG | wavefile.Format.VORBIS) w.close() r = wavefile.WaveReader("file.ogg") self.assertEqual(hex(wavefile.Format.OGG | wavefile.Format.VORBIS | 0), hex(r.format))
def savewav(self, data, filename, samplerate): import os assert not os.access( filename, os.F_OK), "Test temporary file already existed: %s" % filename import wavefile with wavefile.WaveWriter(filename, samplerate=samplerate, channels=data.shape[1]) as writer: writer.write(data.ravel("C").reshape(data.shape)) self.toRemove(filename)
def test_metadata_illegalAttribute(self): self.toRemove("file.wav") w = wavefile.WaveWriter("file.wav", samplerate=22050) w.close() r = wavefile.WaveReader("file.wav") try: self.assertEqual(None, r.metadata.illegalAttribute) self.fail("Exception expected") except AttributeError as e: self.assertEqual(("illegalAttribute", ), e.args) r.close()
def dict_to_wav(a_dict, a_name): keys = list(sorted(a_dict)) name = "{}.wav".format(a_name) with wavefile.WaveWriter( name, channels=1, samplerate=44100, ) as writer: for key in keys[16:70:3]: arr = numpy.array([a_dict[key]]) count = int(SR / arr.shape[1]) for i in range(count): writer.write(arr)
def test_metadata_default(self): self.toRemove("file.wav") w = wavefile.WaveWriter("file.wav", samplerate=22050) w.close() r = wavefile.WaveReader("file.wav") self.assertEqual(None, r.metadata.title) self.assertEqual(None, r.metadata.copyright) self.assertEqual(None, r.metadata.software) self.assertEqual(None, r.metadata.artist) self.assertEqual(None, r.metadata.comment) self.assertEqual(None, r.metadata.date) self.assertEqual(None, r.metadata.album) self.assertEqual(None, r.metadata.license) self.assertEqual(None, r.metadata.tracknumber) self.assertEqual(None, r.metadata.genre) r.close()
def writeWav(self, filename, data): self.toRemove(filename) with wavefile.WaveWriter(filename, channels=data.shape[0]) as w: w.write(data)
def test_channels_byDefault(self): self.toRemove("file.wav") w = wavefile.WaveWriter("file.wav") w.close() r = wavefile.WaveReader("file.wav") self.assertEqual(1, r.channels)
def test_readed_generatedByWaveWriter(self): self.toRemove("file.wav") w = wavefile.WaveWriter("file.wav") r = wavefile.WaveReader("file.wav")
def paulstretch(file_path, stretch, windowsize_seconds, onset_level, outfilename, a_start_pitch, a_end_pitch, a_in_file): if not os.path.exists(file_path): print("Error: {} does not exist.".format(file_path)) return if a_start_pitch is not None: print("Pitch shifting file") f_src_path = file_path f_dest_path = outfilename.replace(".wav", "-tmp.wav") if a_end_pitch is not None and "win" not in sys.platform.lower(): f_cmd = [ os.path.join(INSTALL_PREFIX, "lib", global_pydaw_version_string, "sbsms", "bin", "sbsms"), f_src_path, f_dest_path, "1.0", "1.0", str(a_start_pitch), str(a_end_pitch) ] else: f_cmd = [ os.path.join(INSTALL_PREFIX, "lib", global_pydaw_version_string, "rubberband", "bin", "rubberband"), "-p", str(a_start_pitch), "-R", "--pitch-hq", f_src_path, f_dest_path ] print("Running {}".format(" ".join(f_cmd))) f_proc = subprocess.Popen(f_cmd) f_proc.wait() file_path = f_dest_path f_reader = wavefile.WaveReader(file_path) samplerate = f_reader.samplerate nsamples = f_reader.frames # Set max window size to 1/8th the size of the sample max_window_size = (float(nsamples) / float(samplerate)) * 0.125 if windowsize_seconds > max_window_size: windowsize_seconds = max_window_size nchannels = f_reader.channels outfile = wavefile.WaveWriter(outfilename, channels=nchannels, samplerate=samplerate) #make sure that windowsize is even and larger than 16 windowsize = int(windowsize_seconds * samplerate) if windowsize < 16: windowsize = 16 windowsize = optimize_windowsize(windowsize) windowsize = int(windowsize / 2) * 2 half_windowsize = int(windowsize / 2) smp = numpy.zeros((nchannels, nsamples), numpy.float32, order='F') f_reader.read(smp) #correct the end of the smp end_size = int(samplerate * 0.05) if end_size < 16: end_size = 16 smp[:, nsamples - end_size:nsamples] *= numpy.linspace(1.0, 0.0, end_size) #compute the displacement inside the input file start_pos = 0.0 displace_pos = windowsize * 0.5 #create Hann window window = 0.5 - numpy.cos(numpy.arange(windowsize, dtype='double') * \ 2.0 * numpy.pi / (windowsize - 1)) * 0.5 old_windowed_buf = numpy.zeros((2, windowsize)) hinv_sqrt2 = (1 + numpy.sqrt(0.5)) * 0.5 hinv_buf = 2.0 * (hinv_sqrt2 - (1.0 - hinv_sqrt2) * \ numpy.cos(numpy.arange(half_windowsize, dtype='double') \ * 2.0 * numpy.pi / half_windowsize)) / hinv_sqrt2 freqs = numpy.zeros((2, half_windowsize + 1)) old_freqs = freqs num_bins_scaled_freq = 32 freqs_scaled = numpy.zeros(num_bins_scaled_freq) old_freqs_scaled = freqs_scaled displace_tick = 0.0 displace_tick_increase = 1.0 / stretch if displace_tick_increase > 1.0: displace_tick_increase = 1.0 extra_onset_time_credit = 0.0 get_next_buf = True while True: if get_next_buf: old_freqs = freqs old_freqs_scaled = freqs_scaled #get the windowed buffer istart_pos = int(numpy.floor(start_pos)) buf = smp[:, istart_pos:istart_pos + windowsize] if buf.shape[1] < windowsize: buf = numpy.append(buf, numpy.zeros((2, windowsize - buf.shape[1])), 1) buf = buf * window # get the amplitudes of the frequency components # and discard the phases freqs = numpy.abs(numpy.fft.rfft(buf)) #scale down the spectrum to detect onsets freqs_len = freqs.shape[1] if num_bins_scaled_freq < freqs_len: freqs_len_div = freqs_len // num_bins_scaled_freq new_freqs_len = freqs_len_div * num_bins_scaled_freq freqs_scaled = numpy.mean( numpy.mean(freqs, 0)[:new_freqs_len].reshape( [num_bins_scaled_freq, freqs_len_div]), 1) else: freqs_scaled = numpy.zeros(num_bins_scaled_freq) #process onsets m = 2.0 * numpy.mean(freqs_scaled - old_freqs_scaled) / \ (numpy.mean(numpy.abs(old_freqs_scaled)) + 1e-3) if m < 0.0: m = 0.0 if m > 1.0: m = 1.0 if m > onset_level: displace_tick = 1.0 extra_onset_time_credit += 1.0 cfreqs = (freqs * displace_tick) + (old_freqs * (1.0 - displace_tick)) # randomize the phases by multiplication with a random # complex number with modulus=1 ph = numpy.random.random(size=(nchannels, cfreqs.shape[1])) * (2. * numpy.pi) * 1j cfreqs = cfreqs * numpy.exp(ph) #do the inverse FFT buf = numpy.fft.irfft(cfreqs) #window again the output buffer buf *= window #overlap-add the output output = buf[:,0:half_windowsize] + \ old_windowed_buf[:,half_windowsize:windowsize] old_windowed_buf = buf #remove the resulted amplitude modulation output *= hinv_buf outfile.write(output) if get_next_buf: start_pos += displace_pos get_next_buf = False if start_pos >= nsamples: break if extra_onset_time_credit <= 0.0: displace_tick += displace_tick_increase else: #this must be less than displace_tick_increase credit_get = 0.5 * displace_tick_increase extra_onset_time_credit -= credit_get if extra_onset_time_credit < 0: extra_onset_time_credit = 0 displace_tick += displace_tick_increase - credit_get if displace_tick >= 1.0: displace_tick = displace_tick % 1.0 get_next_buf = True outfile.close() if a_start_pitch is not None: print("Deleting temp file {}".format(file_path)) os.remove(file_path)