Record a piece of audio, change its pitch 50 times and match each new audio to a key on the keyboard, and you can turn the computer into a piano!
A section of audio can be encoded as an array (or list) of numeric values, like this:
We can take a second value off every second of the array to change the speed of the audio to twice times.
So not only did we halve the length of the audio, but we also doubled its frequency so that it had a higher pitch (pitch) than it had previously.
Conversely, if we repeat each of the values in the array, we will get a slower, longer period, that is, a lower pitch audio:
This provides an arbitrary, simple Python function that can change the audio speed by any factor:
Import NumPy as NP
def speedx (Sound_array, Factor): ""
times the audio speed by any factor ' factor ' "" "
indices = Np.round ( Np.arange (0, Len (snd_array), factor))
indices = indices[indices < Len (snd_array)].astype (int) return
sound _array[indices.astype (int)]
The more difficult part of the problem is to change the length of the audio while maintaining its pitch (speed, audio stretching (sound stretching)), or to change the pitch of the audio while maintaining its length (pitch shifting).
variable Speed
The speed change can be achieved by the traditional phase sound coder (phase vocoder, an interested friend can read the Wikipedia page). First, the audio is decomposed into overlapping bits, and then the bits are rearranged so they overlap more (which will shorten the length of the sound) or less (the length of the audio will be stretched), as shown in the following illustration:
The difficulty is that rearranging bits can have a very serious effect on each other, so there is a need to use phase transformations to ensure that they do not affect each other. Here is a piece of Python code, taken from this page (not open, you know.) -Translator Note):
def stretch (Sound_array, F, Window_size, h): "" "The
Audio is" stretched "by coefficient ' f '" "
phase = Np.zeros (window_size)
Hanning_ window = np.hanning (window_size) Result
= Np.zeros (len (Sound_array)/F + window_size)
for I in Np.arange (0, Len (s) Ound_array)-(window_size+h), h*f):
# Two possible overlapping subsequence
a1 = sound_array[i:i + window_size]
a2 = sound_array[i + H : i + window_size + h]
# resynchronize The second sequence by the first sequence
S1 = Np.fft.fft (Hanning_window * a1)
s2 = Np.fft.fft (Hanning_window * A2)
phase = (phase + np.angle (S2/S1))% 2*np.pi
a2_rephased = Np.fft.ifft (np.abs (S2) *np.exp (1j*phase))
# Add to results
i2 = Int (i/f)
Result[i2:i2 + window_size] + = hanning_window*a2_rephased result
= ((2** (16 -4) * Result/result.max ()) # normalized (16bit) return
result.astype (' Int16 ')
modulation
Once you realize the speed change, it's not difficult to change the tone. If you need a higher pitch, you can stretch the audio and keep the pitch unchanged, and then speed it up so that the resulting audio will have the same length of the original audio, the higher frequency, the higher pitch.
Doubling the frequency of a section of audio will increase the pitch by eight degrees, which is 12 chromatic. Therefore, to increase the pitch by N-Chromatic, we need to multiply the frequency by the coefficient 2^ (N/12):
def pitchshift (Snd_array, N, window_size=2**13, h=2**11): "" "" "
to increase the pitch of an audio" ' n ' "a Chromatic" ""
factor = 2** (1.0 * n/12.0) c3/>stretched = Stretch (Snd_array, 1.0/factor, Window_size, h) return
Speedx (stretched[window_size:], Factor)
Small Program: Computer Piano
Let's play with our tonal device. We first hit the bowl to determine a "standard syllable breaks High":
[Youku id= "Xnzm1ndm2ntky"]
Next we create 50 tonal pitches based on the previous audio, from very low to very high:
From Scipy.io import wavfile
fps, bowl_sound = Wavfile.read ("bowl.wav")
tones = range ( -25,25)
transposed = [Pitchshift (Bowl_sound, N) for n in tones]
Next, according to the order in this file, we match each audio to a key in the keyboard, as shown in the following illustration:
We just need to tell the computer in the code to play its corresponding sound when a key is pressed, and then stop playing when the key is released:
Import Pygame pygame.mixer.init (fps,-16, 1, 512) # too flexible Screen = Pygame.display.set_mode ((640,480)) # Set Focus # to get a list of the correct order of keys on the keyboard # ' Keys ' such as [' Q ', ' W ', ' E ', ' R ' ...] arrange the keys = open (' typewriter.kb '). Read (). split (' \ n ') sounds = map (pygame.sndarray.make _sound, transposed) Key_sound = Dict (Zip (keys, sounds)) is_playing = {K:false for k on keys} while true:event = Pygame.event.wait () if Event.type in (Pygame. KEYDOWN, Pygame. KEYUP): Key = Pygame.key.name (Event.key) if Event.type = = Pygame. Keydown:if (Key in Key_sound.keys ()) and (not Is_playing[key]): Key_sound[key].play (fade_ms=50) is_play Ing[key] = True elif Event.key = = Pygame. K_ESCAPE:pygame.quit () raise keyboardinterrupt elif Event.type = Pygame.
KEYUP and Key in Key_sound.keys (): Key_sound[key].fadeout (50) # Stop playing and 50ms fade is_playing[key] = False
So we turned the computer into a piano! At this point, let me show you a Turkish march to express my thanks for your patience in reading this article:
[Youku id= "XNZM1NDQ1MDA4"]
If you want to try it yourself, you can download all the files you need here. Because not all people use Python, I also use JAVASCRIPT/HTML5 (here) to achieve a computer piano, but not particularly ideal. It would be nice to have experienced Html5/js/elm programmers to improve, or rewrite from scratch.
What do we do next?
More often than not, I find that computers are rarely used for performing performances. I understand that using a piano keyboard or recording directly from an instrument can be a lot easier, but see what you can do with just one bowl and 60 lines of Python code!
Even cheap computers have so much control over a mediocre music station: You can sing to the microphone, sign the camera, use the mouse to modulate, and then use the keyboard to complete the rest of the stuff. There are so many ways to express yourself, and every way there is a python bag ... Are there any great gods with artistic gifts to join?