0

在一个小型游戏项目中,我使用 FM、Sine 和 Square 媒体合成来制作游戏音乐,以使其体积小巧并具有复古感。
我有三个音频通道,每个通道都有一个播放器,然后我将文本文件中的所有音符排队。然后我将所有播放器放入一个 pyglet media PlayerGroup 以同步音乐的开始、停止和暂停。我的问题是我希望播放器组循环播放,或者三个单独的曲目。
  1. PlayerGroup.loop:

设置 playergroup.loop = True 似乎没有任何影响。在所有三个频道的队列都完成后,音乐停止。

  1. 循环播放各个媒体播放器

在将组中的各个音乐播放器添加到播放器组之前将它们设置为循环只会使第一个音符循环。

我已经用可以执行的完整代码示例更新了这个问题。您可以下载此文本文件并将其放在与 python 代码相同的文件夹中以运行它:https://www.mma.com/musik.txt

那么有谁知道如何循环 Python Pyglet 媒体播放器组?

# sound.py

import pyglet

class GameMusic:
    def __init__(self, music_filename="musik.txt", mainvolume=0.5):
        self.decay_quick = pyglet.media.synthesis.LinearDecayEnvelope(0.2)
        self.adsr_quick = pyglet.media.synthesis.ADSREnvelope(0.1, 0.15, 0.25, 0.1)
        self.adsr_slow = pyglet.media.synthesis.ADSREnvelope(0.4, 0.3, 0.4,0.4)
        self.sine = pyglet.media.synthesis.Sine(duration=0.1, frequency=220, envelope=self.decay_quick)
        self.noise = pyglet.media.synthesis.WhiteNoise(duration=0.05)
        self.attack = pyglet.media.synthesis.FM(0.1, carrier=280, modulator=8, mod_index=4, envelope=self.decay_quick)
        self.fm1 = pyglet.media.synthesis.FM(0.4, carrier=440, modulator=220, mod_index=4, envelope=self.adsr_quick)
        self.fm2 = pyglet.media.synthesis.FM(0.4, carrier=392, modulator=98, mod_index=2, envelope=self.adsr_quick)
        self.fm3 = pyglet.media.synthesis.FM(1.2, carrier=659.25, modulator=61.74, mod_index=3, envelope=self.adsr_slow)
        self.event_player = pyglet.media.Player()
        with open(music_filename, "r") as filestream:
            row = 0
            self.music_player_1 = pyglet.media.Player()
            self.music_player_2 = pyglet.media.Player()
            self.music_player_3 = pyglet.media.Player()

            for line in filestream:
                if row == 0:
                    currentline = line.split(",")
                    tot_notes = int(currentline[0])
                    channels = int(currentline[1])
                else:
                    currentline = line.split(",")
                    for a in range(0,len(currentline)-1,1):
                        note_length = (2.0 / int(currentline[a][0]))
                        if row == 1:
                            self.music_player_1.queue(self.get_note_frequency(currentline[a][1], note_length,row))
                        elif row == 2:
                            self.music_player_2.queue(self.get_note_frequency(currentline[a][1], note_length,row))                    
                        else:
                            self.music_player_3.queue(self.get_note_frequency(currentline[a][1], note_length,row))                    
                row=row+1        

            self.my_player_group = pyglet.media.PlayerGroup([self.music_player_1, self.music_player_2, self.music_player_3])
        
    def pause(self):
        self.my_player_group.pause()
    
    def play(self):
        self.my_player_group.loop = True
        self.my_player_group.play()
    
    def encounter(self):
        self.event_player.loop = False
        self.event_player.queue(self.fm1)
        self.event_player.queue(self.fm2)
        self.event_player.queue(self.fm3)
        self.event_player.play()
        
    def blipp(self):
        self.event_player.loop = False
        self.event_player.queue(self.sine)
        self.event_player.play()

    def attack_hit(self):
        self.event_player.loop = False
        self.event_player.queue(self.attack)
        self.event_player.play()

    def monster_hit(self):
        self.event_player.loop = False
        self.event_player.queue(self.noise)
        self.event_player.play()
        
    def tick(self):
        pass
        
    def __del__(self):
        self.event_player.delete()
#        self.my_player_group.delete()
    
    def get_note_frequency(self, note_letter, note_length,channel):
        bas_noter = [220.0, 246.94, 261.63, 293.66, 329.63, 349.23, 392.00]
        diskant_noter = [440.00,493.88, 523.25, 587.33, 659.25, 698.46, 783.99, 880.0, 987.77, 1046.50]

        if (note_letter == "P"):
            return pyglet.media.synthesis.Silence(duration=note_length)        

        elif note_letter.islower() == True:
            # Bas notes.
            note_frequency = bas_noter[ord(note_letter)-ord("a")]            
        elif note_letter.isupper() == True:
            note_frequency = diskant_noter[ord(note_letter)-ord("A")]
        else:
            # Something is wrong
            return pyglet.media.synthesis.WhiteNoise(duration=0.25)
        if channel == 1:
            return pyglet.media.synthesis.Sine(duration=note_length, frequency=note_frequency, envelope=self.adsr_slow)        
        elif channel == 2:
            return pyglet.media.synthesis.Square(duration=note_length, frequency=note_frequency/2, envelope=self.adsr_quick)        
        else:
            return pyglet.media.synthesis.FM(duration=note_length, carrier=note_frequency, modulator=(note_frequency/4), mod_index=16, envelope=self.decay_quick)
            
# Temporary test generator. 
if __name__ == "__main__":
    music = GameMusic()
    window = pyglet.window.Window()
    music.play()

    pyglet.app.run()    
    
    pass
4

0 回答 0