Original link:tecdat.cn/?p=7620
Original source:Tuo End number according to the tribe public number
One second from a 44.1khz single-channel.wav file can be read into an array of length 44100 (called B). Given A matrix A, we seek A solution to the system Ax is equal to b. Through gauss-Seidel iteration, vector if we record the recording of B, take some white noise as our initial guess, and write Ax in each alternation, we will observe that the high-pitched notes in B first become audible, while the tonal decomposition of white noise occurs.
Initial 12 seconds. Wav file audio (white noise) initialax.wav
Graph of initial Ax, residuals and residuals FFT:
After one iteration, the tweeter is converted to gausS_SEidel_out000000.wav
Some structures can be seen in the spectrum:
Second iteration: gausS_seidel_OUT000001.wav
Third iteration: gausS_seidEL_OUT000002.wav
Fourth iteration: gausS_SEidel_OUT000003.wav
This is all done in Python. Loading.wav files into arrays works fine in SCIpy. To avoid caching problems, the sparse matrix class must be used, because a 12-second.wav file requires an array of size 12 * 44100. Here’s a snippet of the TridiagonalMatrix class I used:
from numpy import *
#a tridiagonal matrix class
class TridiagonalMatrix:
#initialize with 3 numpy arrays
def __init__(self, upper_in, diag_in, lower_in) :
self.upper = upper_in
self.diag = diag_in
self.lower = lower_in
self.dim = diag_in.shape[0]
#matrix mulitplication
def apply(self, v) :
out = ndarray(self.dim)
try:
out[0] = self.diag[0]*v[0] + self.upper[0]*v[1]
out[self.dim-1] = self.lower[self.dim-2]*v[self.dim-2] + self.diag[self.dim-1]*v[self.dim-1]
for i in range(1, self.dim-1):
out[i] = self.lower[i-1]*v[i-1] + self.diag[i]*v[i] + self.upper[i]*v[i+1]
except(IndexError):
print "Wrong sizes"
return out
Copy the code
This is a code snippet that handles reading/writing.wav files and then converting them to a linear system using gauss-seidel.
from TridiagonalMatrix import *
from numpy import *
from scipy.io import wavfile
import scipy.fftpack
import pylab
import sys
import os
def musical_gauss_seidel(A, b, x0, tol) :
""" do the gauss seidel iteration but output some sound every now and then.. A is some matrix that lets gauss seidel work b is a vector that represents a .wav file of a pretty song x0 is our initial guess for the gauss seidel method (probably random static) we are going to output the .wav data corresponding to Ax as Ax gets closer to b (ie the residual gets smaller) we should hear the song emerge from the initial guess """
#make noise of the initial approximation to b
wavfile.write("gauss_seidel_out000000.wav".44100, (A.apply(x0)).astype(int16))
residual = A.apply(x0) - b
Copy the code