CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
amanchadha

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: amanchadha/coursera-deep-learning-specialization
Path: blob/master/C5 - Sequence Models/Week 1/Jazz improvisation with LSTM/midi.py
Views: 4819
1
"""
2
File: midi.py
3
Author: Addy771
4
Description:
5
A script which converts MIDI files to WAV and optionally to MP3 using ffmpeg.
6
Works by playing each file and using the stereo mix device to record at the same time
7
"""
8
9
10
import pyaudio # audio recording
11
import wave # file saving
12
import pygame # midi playback
13
import fnmatch # name matching
14
import os # file listing
15
16
17
#### CONFIGURATION ####
18
19
do_ffmpeg_convert = True # Uses FFmpeg to convert WAV files to MP3. Requires ffmpeg.exe in the script folder or PATH
20
do_wav_cleanup = True # Deletes WAV files after conversion to MP3
21
sample_rate = 44100 # Sample rate used for WAV/MP3
22
channels = 2 # Audio channels (1 = mono, 2 = stereo)
23
buffer = 1024 # Audio buffer size
24
mp3_bitrate = 128 # Bitrate to save MP3 with in kbps (CBR)
25
input_device = 1 # Which recording device to use. On my system Stereo Mix = 1
26
27
28
29
# Begins playback of a MIDI file
30
def play_music(music_file):
31
32
try:
33
pygame.mixer.music.load(music_file)
34
35
except pygame.error:
36
print ("Couldn't play %s! (%s)" % (music_file, pygame.get_error()))
37
return
38
39
pygame.mixer.music.play()
40
41
42
43
# Init pygame playback
44
bitsize = -16 # unsigned 16 bit
45
pygame.mixer.init(sample_rate, bitsize, channels, buffer)
46
47
# optional volume 0 to 1.0
48
pygame.mixer.music.set_volume(1.0)
49
50
# Init pyAudio
51
format = pyaudio.paInt16
52
audio = pyaudio.PyAudio()
53
54
55
56
try:
57
58
# Make a list of .mid files in the current directory and all subdirectories
59
matches = []
60
for root, dirnames, filenames in os.walk("./"):
61
for filename in fnmatch.filter(filenames, '*.mid'):
62
matches.append(os.path.join(root, filename))
63
64
# Play each song in the list
65
for song in matches:
66
67
# Create a filename with a .wav extension
68
file_name = os.path.splitext(os.path.basename(song))[0]
69
new_file = file_name + '.wav'
70
71
# Open the stream and start recording
72
stream = audio.open(format=format, channels=channels, rate=sample_rate, input=True, input_device_index=input_device, frames_per_buffer=buffer)
73
74
# Playback the song
75
print("Playing " + file_name + ".mid\n")
76
play_music(song)
77
78
frames = []
79
80
# Record frames while the song is playing
81
while pygame.mixer.music.get_busy():
82
frames.append(stream.read(buffer))
83
84
# Stop recording
85
stream.stop_stream()
86
stream.close()
87
88
89
# Configure wave file settings
90
wave_file = wave.open(new_file, 'wb')
91
wave_file.setnchannels(channels)
92
wave_file.setsampwidth(audio.get_sample_size(format))
93
wave_file.setframerate(sample_rate)
94
95
print("Saving " + new_file)
96
97
# Write the frames to the wave file
98
wave_file.writeframes(b''.join(frames))
99
wave_file.close()
100
101
# Call FFmpeg to handle the MP3 conversion if desired
102
if do_ffmpeg_convert:
103
os.system('ffmpeg -i ' + new_file + ' -y -f mp3 -ab ' + str(mp3_bitrate) + 'k -ac ' + str(channels) + ' -ar ' + str(sample_rate) + ' -vn ' + file_name + '.mp3')
104
105
# Delete the WAV file if desired
106
if do_wav_cleanup:
107
os.remove(new_file)
108
109
# End PyAudio
110
audio.terminate()
111
112
except KeyboardInterrupt:
113
# if user hits Ctrl/C then exit
114
# (works only in console mode)
115
pygame.mixer.music.fadeout(1000)
116
pygame.mixer.music.stop()
117
raise SystemExit
118