Use Python to turn a computer into a piano

Source: Internet
Author: User

Record a piece of audio, change its pitch 50 times and match each new audio to a keyboard key, and you can turn your computer into a piano!

A piece of audio can be encoded as an array (or list) of values, like this:

  

We can change the speed of this audio to twice times by taking a second value in the array every second:

  

So we not only halved the length of the audio, but also doubled its frequency so that it had a higher pitch (pitch) than the original.

Conversely, if we repeat each value in the array once, we will get a slower, longer period, or lower pitch audio:

  

Here is a simple Python function that can change the audio speed by any factor:

Python

1

2

3

4

5

6

7import NumPy as NP

def speedx (Sound_array, Factor):

"" To multiply 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 changing the audio length while maintaining its pitch (variable speed, audio stretching), or changing the pitch of the audio while maintaining its length (pitch shifting).

Variable speed

The variable speed can be achieved through the traditional phase sound encoder (phase vocoder, interested friends can read the Wikipedia page). First, the audio is decomposed into overlapping bits, and then the bits are rearranged so that they overlap more (the length of the sound will be shortened) or less (the length of the audio will be stretched), as shown in:

  

The difficulty is that the rearranged bits can be very heavily interacting with each other, so there is a need for phase transformations to ensure that there is no effect between them. Here is a Python code, taken from this page (if you can't open it, you know.) --Translator's note):

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21st

22

23

24

25

26def Stretch (Sound_array, F, Window_size, h):

"" Stretch the audio by factor ' 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 (sound_array)-(window_size+h), h*f):

# Two sub-sequences that may overlap each other

A1 = Sound_array[i:i + Window_size]

A2 = sound_array[i + h:i + window_size + h]

# re-sync 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 have achieved the speed change, the pitch is not difficult. If you need a higher pitch, you can stretch the audio and keep the pitch constant, then speed it up so that the final audio will have the same length as the original audio, higher frequencies, or higher pitches.

Doubling the frequency of a piece of audio will increase the pitch by a factor of eight, which is 12 chromatic. Therefore, to increase the pitch by N-Chromatic, we need to multiply the frequency by the coefficient 2^ (N/12):

Python

1

2

3

4

5def Pitchshift (Snd_array, N, window_size=2**13, h=2**11):

"" To increase the pitch of a piece of audio by ' n ' and ' ""

Factor = 2** (1.0 * n/12.0)

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 pitch shifter. We first hit the bowl to determine a "standard pitch high":

Next we create 50 pitch pitches based on the previous audio, from very low to very high:

Python

1

2

3

4

5from 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, based on the order in this file, we match each audio to a key on the keyboard, as shown in:

  

We just need to tell the computer in the code to play its corresponding sound when a key is pressed down, and then stop playing when the button is released:

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21st

22

23

24

25

26

27

28

29

30

31

32

33

34import Pygame

Pygame.mixer.init (FPS,-16, 1, 512) # too flexible;)

Screen = Pygame.display.set_mode ((640,480)) # Set focus

# Get a list of keyboard keys in the correct order

# "Keys" as arranged as [' Q ', ' W ', ' E ', ' R ' ...]

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 in 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_playing[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 playback and 50ms fade out

Is_playing[key] = False

So we turned the computer into a piano! Now, let me show you a turkey march to express your appreciation for your patience in reading this article:

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 an experienced Html5/js/elm programmer to improve the improvement, or rewrite it from scratch.

What do you do next?

More generally, I find that computers are seldom used for performing performances. I understand that it is much easier to use a piano keyboard or to record directly from an instrument, but see what you can do with just one bowl and 60 lines of Python code!

Even a cheap computer has so much control to achieve a so-called music platform: You can sing to the microphone, gesture to the camera, use the mouse to modulate, and then use the keyboard to do the rest of the stuff. There are so many ways to express yourself, and there is a Python package in each of these ways ... Is there a great God with artistic talent to join?

Use Python to turn a computer into a piano

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.