pygame.mixer.music.play()无法识别“快速跟踪"(.xm音乐格式)重复位置 [英] pygame.mixer.music.play() doesn't recognize Fast Tracker (.xm music format) repeat position

查看:641
本文介绍了pygame.mixer.music.play()无法识别“快速跟踪"(.xm音乐格式)重复位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是:

我尝试无限循环播放Fast Tracker模块,但是这样做只是从头开始播放音乐,而不是跟随重复的位置.

I try to play Fast Tracker module in infinite loop, but doing so just replay music from start, instead of following repeat position.

示例: (这是模块 https://api.modarchive.org/downloads.php?moduleid=153915#zeta_force_level_2.xm )

import pygame

pygame.mixer.init()
pygame.mixer.music.load('/path/to/zeta_force_level_2.xm')
pygame.mixer.music.play(-1)

我要实现的目标:循环播放模块音乐,每次在重复位置而不是在曲目开始时循环播放.不必使用pygame:之所以使用它,是因为我没有找到适合播放跟踪器音乐的任何内容

What I'm trying to achieve: Play module music in loop, each time looping on repeat position, not on start of track. Use of pygame isn't necessary: I use it because I didn't found anything suitable for playing tracker music

谢谢.

推荐答案

更新:我在cython中编写了一个简单的演示,可以成功播放链接的.xm文件.它基本上是此c演示代码的翻译. .我的代码可以在此github页面中找到.为了使其在Ubuntu中工作,我必须安装libxmp-dev软件包.请注意,目前所有内容都已进行硬编码,因此需要对其进行重构以在项目中更直接地使用.

Update: I wrote a simple demo in cython that successfully plays your linked .xm file. It basically is a translation of this c demo code. My code for it can be found on this github page. For getting it to work in Ubuntu, I had to install the libxmp-dev package. Note that everything is hardcoded in at the moment, so it would need to be refactored to be more directly usable in your project.

这绝不是一个肯定的答案.在此过程中,我遇到了许多潜在的陷阱,这使我怀疑pygame是否是适合此工作的工具,但是我将介绍我到目前为止发现的内容以及一些建议.

This is by no means a conclusive answer. I ran into many potential pitfalls along the way that make me doubt if pygame is the right tool for the job here, but I will present what I have found out so far as well as some suggestions.

.xm快速跟踪器 MOD 格式看起来与典型的wav/ogg/mp3文件不同,因为您可以组合不同的MIDI,而不仅仅是播放示例数据乐器和样本共同创建您的音乐,就像问题中链接的(甜)chiptune一样.

It looks like the .xm Fast Tracker MODule format is different from your typical wav/ogg/mp3 file in that rather than just playing an array of sample data, you can combine different MIDI instruments and samples together to create you music, like the (sweet) chiptune linked in the question.

事实证明,SDL/pygame可以播放此类文件,但方式相当有限.查看pygame的音乐模块,有一个set_pos函数.但是,尝试使用它给了我pygame.error: set_pos unsupported for this codec.但是,有趣的是,我可以通过将pygame.mixer.music.play与可选的start关键字结合使用来解决此问题.虽然大多数文件格式上的start只是开始播放文件前的偏移量(以秒为单位)(仅在歌曲的第一个播放过程中),但对于MOD文件(如问题中的.xm文件)而言,它具有不同的含义. 显然,它对应于MOD文件中的pattern数字.因此,根据每种模式在文件中的起始位置,可以在pygame中使用的潜在起点数量非常有限.

It turns out that SDL/pygame, can play such files, but in a rather limited way. Looking at pygame's music module, there is a set_pos function. However, trying to use that gave me a pygame.error: set_pos unsupported for this codec. Interestingly however, I was able to work around this by using pygame.mixer.music.play with the optional start keyword. While start on most file formats is simply the offset in seconds before starting the file (only on the first playthrough of the song), it has a different meaning for MOD files like the .xm file in the question. Apparently, it corresponds to a pattern number in the MOD file. As a result, there are a very limited number of potential starting points that can be used in pygame, based on where each pattern starts in the file.

如果您想从一个特定的模式号开始,那么下面的代码就足够循环了.请注意,我使用pygame的事件系统查看声音何时完成,以使用适当的模式偏移"循环"声音文件:

If you have a specific pattern number you want to start from in mind, then the following code would be sufficient to loop. Note that I use pygame's event system to see when the sound is finished to "loop" the sound file with the appropriate "pattern offset":

import pygame

pygame.init()
pygame.mixer.music.load('zeta_force_level_2.xm')
pattern = 10
loop_event = pygame.USEREVENT + 1
pygame.mixer.music.set_endevent(loop_event)
pygame.mixer.music.play(start=pattern)

while True:
    for event in pygame.event.get():
        if event.type == loop_event:
            pygame.mixer.music.play(start=pattern)

在这一点上,您可能想知道这些patterns到底是什么?如果您的系统上安装了ffmpeg,则可以在文件上运行ffprobe并获得以下输出:

At this point, you might be wondering what exactly are these patterns? If you have ffmpeg installed on your system, you can run ffprobe on your file and get the following output:

Input #0, libmodplug, from 'zeta_force_level_2.xm':
  Metadata:
    name            : zeta force level 2
    instrument      : by zabutom --
                    : bye bye computer..
                    : see you in a week
    sample          : zeta force level 2
    extra info      : 20 patterns, 10 channels, 3/14 instruments, 1/14 sample
  Duration: 00:01:01.00, bitrate: 3 kb/s
    Stream #0:0: Audio: pcm_s16le, 44100 Hz, 2 channels, s16, 1411 kb/s

此文件中似乎有20种模式,您可以从中选择作为循环的起始位置.要获取有关特定文件的更多信息,可以使用MilkyTracker之类的工具打开(并编辑!)文件,并获得如下输出:

It looks like there are 20 patterns in this file from which you can choose as your starting location for the loop. To get more information about your particular file, you can open (and edit!) your file in a tool like MilkyTracker and get an output like this:

youtube上有一些MilkyTracker的在线教程,但看起来像是一个非常复杂的软件.

There are some tutorials for MilkyTracker online on youtube, but it looks like a pretty complicated piece of software.

似乎还存在一个名为 libxmp 的库及其相应的pyaudio这样的库中播放,也可以在任何与OpenAL绑定的python中播放.无论哪种方式,看来您都在为您完成工作!

There also appears to be a library called libxmp and its corresponding python binding. This should handle the conversion required to "render" MOD file data into a simple PCM array that can be played in a library like pyaudio or any python binding to OpenAL. Either way, it looks like you have your work cut out for you!

这篇关于pygame.mixer.music.play()无法识别“快速跟踪"(.xm音乐格式)重复位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆