Python 如何从Music21制作的音乐中生成实时音频输出?

Python 如何从Music21制作的音乐中生成实时音频输出?,python,music21,audio,Python,Music21,Audio,如何从使用Music21制作的音乐中生成实时音频输出。否则,如何通过开源软件从Music21制作的音乐中产生任何音频输出?谢谢你的帮助。以下是我的发现。下面是一个在WindowsXP上运行的python脚本。除了音乐,它还需要pygame 21 # genPlayM21Score.py Generates and Plays 2 Music21 Scores "on the fly". # # see way below for source notes from music21 import

如何从使用Music21制作的音乐中生成实时音频输出。否则,如何通过开源软件从Music21制作的音乐中产生任何音频输出?谢谢你的帮助。

以下是我的发现。下面是一个在WindowsXP上运行的python脚本。除了音乐,它还需要pygame 21

# genPlayM21Score.py Generates and Plays 2 Music21 Scores "on the fly".
#
# see way below for source notes

from music21 import *

# we create the music21 Bottom Part, and do this explicitly, one object at a time.

n1 = note.Note('e4')
n1.duration.type = 'whole'
n2 = note.Note('d4')
n2.duration.type = 'whole'
m1 = stream.Measure()
m2 = stream.Measure()
m1.append(n1)
m2.append(n2)
partLower = stream.Part()
partLower.append(m1)
partLower.append(m2)

# For the music21 Upper Part, we automate the note creation procedure

data1 = [('g4', 'quarter'), ('a4', 'quarter'), ('b4', 'quarter'), ('c#5', 'quarter')]
data2 = [('d5', 'whole')]
data = [data1, data2]
partUpper = stream.Part()

def makeUpperPart(data):
    for mData in data:
        m = stream.Measure()
        for pitchName, durType in mData:
            n = note.Note(pitchName)
            n.duration.type = durType
            m.append(n)
        partUpper.append(m)
makeUpperPart(data)        

# Now, we can add both Part objects into a music21 Score object.  

sCadence = stream.Score()
sCadence.insert(0, partUpper)
sCadence.insert(0, partLower)

# Now, let's play the MIDI of the sCadence Score [from memory, ie no file  write necessary] using pygame

import cStringIO

# for music21 <= v.1.2:
if hasattr(sCadence, 'midiFile'):
   sCadence_mf = sCadence.midiFile
else: # for >= v.1.3:
   sCadence_mf = midi.translate.streamToMidiFile(sCadence)
sCadence_mStr = sCadence_mf.writestr()
sCadence_mStrFile = cStringIO.StringIO(sCadence_mStr)

import pygame

freq = 44100    # audio CD quality
bitsize = -16   # unsigned 16 bit
channels = 2    # 1 is mono, 2 is stereo
buffer = 1024    # number of samples
pygame.mixer.init(freq, bitsize, channels, buffer)

# optional volume 0 to 1.0
pygame.mixer.music.set_volume(0.8)

def play_music(music_file):
    """
    stream music with mixer.music module in blocking manner
    this will stream the sound from disk while playing
    """
    clock = pygame.time.Clock()
    try:
        pygame.mixer.music.load(music_file)
        print "Music file %s loaded!" % music_file
    except pygame.error:
        print "File %s not found! (%s)" % (music_file, pygame.get_error())
        return
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        # check if playback has finished
        clock.tick(30)

# play the midi file we just saved
play_music(sCadence_mStrFile)

#============================

# now let's make a new music21 Score by reversing the upperPart notes
data1.reverse()
data2 = [('d5', 'whole')]
data = [data1, data2]
partUpper = stream.Part()
makeUpperPart(data)        
sCadence2 = stream.Score()
sCadence2.insert(0, partUpper)
sCadence2.insert(0, partLower)

# now let's play the new Score
sCadence2_mf = sCadence2.midiFile
sCadence2_mStr = sCadence2_mf.writestr()
sCadence2_mStrFile = cStringIO.StringIO(sCadence2_mStr)
play_music(sCadence2_mStrFile)



## SOURCE NOTES
## There are 3 sources for this mashup:

# 1. Source for the Music21 Score Creation http://web.mit.edu/music21/doc/html/quickStart.html#creating-notes-measures-parts-and-scores

# 2.  Source for the Music21 MidiFile Class Behaviour http://mit.edu/music21/doc/html/moduleMidiBase.html?highlight=midifile#music21.midi.base.MidiFile

# 3.  Source for the pygame player: http://www.daniweb.com/software-development/python/code/216979/embed-and-play-midi-music-in-your-code-python
#genPlayM21Score.py“动态”生成并播放2个音乐21乐谱。
#
#有关源代码注释,请参见下面的方法
从music21导入*
#我们创建music21底部部分,并明确地一次创建一个对象。
n1=注释。注释('e4')
n1.duration.type='整个'
n2=注释。注释('d4')
n2.duration.type='整个'
m1=stream.Measure()
m2=stream.Measure()
m1.追加(n1)
m2.附加(n2)
partLower=stream.Part()
partLower.append(m1)
零件下部。附加(m2)
#对于music21上部,我们自动执行音符创建过程
数据1=[('g4','quarter'),('a4','quarter'),('b4','quarter'),('c#5','quarter')]
数据2=[('d5','整个')]
数据=[data1,data2]
partUpper=stream.Part()
def makeUpperPart(数据):
对于数据中的mData:
m=stream.Measure()
对于pitchName,请键入mData:
n=注释。注释(pitchName)
n、 duration.type=durType
m、 附加(n)
partUpper.append(m)
makeUpperPart(数据)
#现在,我们可以将两个Part对象添加到music21 Score对象中。
sCadence=stream.Score()
sCadence.insert(0,partUpper)
sCadence.insert(0,零件更低)
#现在,让我们使用pygame[从内存中]播放sCadence乐谱的MIDI
导入cStringIO
#对于音乐21=v.1.3:
sCadence_mf=midi.translate.streamToMidiFile(sCadence)
sCadence\u mStr=sCadence\u mf.writestr()
sCadence\u mStrFile=cStringIO.StringIO(sCadence\u mStr)
导入pygame
频率=44100#音频CD质量
位大小=-16#无符号16位
通道=2#1为单声道,2为立体声
缓冲区=1024#样本数
pygame.mixer.init(频率、比特大小、通道、缓冲区)
#可选卷0到1.0
pygame.mixer.music.set_音量(0.8)
def播放音乐(音乐文件):
"""
以分块方式使用mixer.music模块播放音乐
这将在播放时从磁盘流式播放声音
"""
clock=pygame.time.clock()
尝试:
pygame.mixer.music.load(音乐文件)
打印“已加载音乐文件%s!”%Music\u文件
除了pygame.error:
打印“未找到文件%s!(%s)”%(音乐文件,pygame.get\u错误()
返回
pygame.mixer.music.play()
而pygame.mixer.music.get_busy():
#检查播放是否已完成
时钟滴答(30)
#播放我们刚刚保存的midi文件
播放音乐(sCadence\u mStrFile)
#============================
#现在让我们通过颠倒上半部音符来制作一个新的音乐21乐谱
data1.reverse()
数据2=[('d5','整个')]
数据=[data1,data2]
partUpper=stream.Part()
makeUpperPart(数据)
sCadence2=stream.Score()
sCadence2.插入件(0,零件上部)
sCadence2.插入件(0,零件下部)
#现在让我们播放新的乐谱
sCadence2_mf=sCadence2.midiFile
sCadence2_mStr=sCadence2_mf.writestr()
sCadence2_mStrFile=cStringIO.StringIO(sCadence2_mStr)
播放音乐(sCadence2\u mStrFile)
##来源说明
##此mashup有3个来源:
# 1. 音乐21乐谱创作的来源http://web.mit.edu/music21/doc/html/quickStart.html#creating-notes测量零件和分数
# 2.  Music21 MidiFile类行为的源代码http://mit.edu/music21/doc/html/moduleMidiBase.html?highlight=midifile#music21.midi.base.MidiFile
# 3.  pygame玩家的来源:http://www.daniweb.com/software-development/python/code/216979/embed-and-play-midi-music-in-your-code-python

正如您所见,music21并非设计为音乐播放系统,而是设计为嵌入到其他播放系统中或从系统中调用它们。我们不打算在播放系统上投入太多的工作(因为硬件支持,我们是一个小型的研究实验室,音乐分析等方面的工作仍然需要完成),但您的解决方案非常优雅,现在作为music21.midi.realtime模块包含在所有版本的music21(v1.1之后)中。下面是一个示例,它利用music21动态分配具有不同音高弯曲对象的midi通道的能力来模拟微调播放(大多数midi播放的一个主要问题):


StreamPlayer的.play()函数还可以接受busyFunction、busyArgs和busywaitmillizes参数,这些参数指定最多每busywaitmillizes调用一个函数(如果系统速度较慢,则可能会更多)。还有一个endFunction和endArgs,如果您想设置某种线程播放,它们将在最后被调用。-Myke Cuthbert(音乐21创作者)

你的问题相当模糊。到底是什么问题?还有,你有吗?我不同意——这个问题在被问到的时候非常集中,解决方案促使工具包本身发生了变化。为什么要关闭它?该工具包现在有一个
.show('midi')
选项,这正是OP想要的。这个问题没有含糊之处,尽管它相当简单。
#  Set up a detuned piano 
#  (where each key has a random 
#  but consistent detuning from 30 cents flat to sharp)
#  and play a Bach Chorale on it in real time.

from music21 import *
import random
keyDetune = []
for i in range(0, 127):
    keyDetune.append(random.randint(-30, 30))

b = corpus.parse('bach/bwv66.6')
for n in b.flat.notes:
    n.microtone = keyDetune[n.midi]
sp = midi.realtime.StreamPlayer(b)
sp.play()