I have a working function that takes in a Wav file and generates a CWT image of the wav. This is what my first function does. In the second function i try to do the reverse, but i have problems understanding the pywt documentation. The target i try to achive is get back the same wave file (if possible same checksum). But somehow no matter what i deliver to idwt as input i cant get any wav file out.
Either it says the wavelet class is for discrete wavelets and cmor is a continuouts wavelet (i dont get what that means) or it complains that wavelet being able to convert to a float.
import wave
import pywt
import numpy as np
from PIL import Image
def create_cwt_image(wave_file, image_file):
with wave.open(wave_file, 'r') as wav:
# Read wave file
data = wav.readframes(wav.getnframes())
data = np.frombuffer(data, dtype=np.int16)
# Compute wavelet scalogram
wavelet = 'cmor1-1.5'
scales = np.arange(1, 129)
cwtmatr, freqs = pywt.cwt(data, scales, wavelet, 1)
cwtmatr = abs(cwtmatr)
# Normalize wavelet scalogram to [0, 255] range
cwtmatr = cwtmatr / cwtmatr.max() * 255
cwtmatr = cwtmatr.astype(np.uint8)
# Save wavelet scalogram as image
Image.fromarray(cwtmatr, 'L').save(image_file)
def reverse_cwt_image(image_file, wave_file):
# Read CWT image and convert to numpy array
image = Image.open(image_file)
image_data = np.array(image)
# Convert image data to float32 and normalize to [0, 1] range
image_data = image_data.astype(np.float32) / 255
image_data = abs(image_data)
# Compute inverse CWT
wavelet = 'cmor'
w = pywt.Wavelet(wavelet)
cA, cD = pywt.dwt(image_data, wavelet=w, mode='constant')
data = pywt.idwt(cA, cD, None, wavelet, 'symetric')
data = np.array(data, dtype=np.int16)
# Save data as wav file
with wave.open(wave_file, 'w') as wav:
wav.setnchannels(1)
wav.setsampwidth(2)
wav.setframerate(44100)
wav.writeframes(data)
if __name__ == "__main__":
print("now converting wav to spectrogram")
create_cwt_image("1.wav", "spectrogram.png")
print("now converting spectrogram to wav")
reverse_cwt_image("spectrogram.png", "2.wav")
This is the code i have so far, but no matter how i try i can not convert the huge image back to a wav and would appreciate someone helping me.