首页 文章

Libgdx,改变音乐的音调

提问于
浏览
2

我想实现一个很酷的效果,当爆炸时,音乐会稍微变慢一些 .

libgdx的 Music 类不允许改变声音的音高,我尝试使用 Sound 类而不是 Music 来播放我的音乐,但它在加载文件时非常慢(对于5 mb文件,在桌面上为5秒! ) .

所以, question is 如果有办法解决这个问题,或者有一个外部库,它可以在桌面和Android上运行,并且可以与libgdx一起使用 .

3 回答

  • 1

    经过一些搜索,我找到了一种编辑libgdx源代码的方法 .

    您需要使用 AudioDevice 对象按样本播放音乐样本,为此,您需要包含libgdx的音频扩展名 .

    我们将编辑libgdx源代码,因此您需要下载它并用正确的libgdx项目替换gdx.jar,gdx-backend-android.jar和gdx-backend-lwjgl.jar(它们具有相同的名称而没有jar扩展名)

    1)Edit the AudioDevice.java inside com.badlogic.gdx.audio package of the gdx project

    在界面中添加以下代码

    public void setSpeed(float val);
    

    2)Edit the AndroidAudioDevice.java inside com.badlogic.gdx.backends.android package of the gdx-backend-android project

    AudioDevice类的Android端依赖于Android sdk的AudioTrack类,这个类有一个 setPlaybackRate(..) 方法 .

    在类中添加以下代码

    @Override
    public void setSpeed (float speed) {
        track.setPlaybackRate((int)(track.getSampleRate()*speed));
    }
    

    3)Edit the OpenALAudioDevice.java inside com.badlogic.gdx.backends.lwjgl.audio package of the gdx-backend-lwjgl project

    AudioDevice的桌面端依赖于OpenAL(音频的opengl),它具有方便的设置间距方法

    在类中添加以下内容

    @Override
    public void setSpeed (float speed) {
        alSourcef(sourceID, AL_PITCH, speed);
    }
    

    4)Play the audio

    这是加载和播放声音文件的代码

    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.audio.AudioDevice;
    import com.badlogic.gdx.audio.io.Mpg123Decoder;
    import com.badlogic.gdx.files.FileHandle;
    
    public class MusicBeat {
    
    static short[] samples = new short[2048];
    Mpg123Decoder decoder;
    AudioDevice device;
    static FileHandle externalFile;
    public boolean playing=true;
    public MusicBeat(String name )
    {
            FileHandle file=Gdx.files.internal(name);
            FileHandle external=Gdx.files.external("myappname/"+name);
            if(!external.exists())file.copyTo(external); //copy the file to the external storage only if it doesnt exists yet
            decoder = new Mpg123Decoder(external);
            device = Gdx.audio.newAudioDevice(decoder.getRate(),decoder.getChannels() == 1 ? true : false);
            playing=false;
            externalFile=file;
    }
    
    void play()
    {
        playing=true;
        Thread playbackThread = new Thread(new Runnable() {
            @Override
            public synchronized  void run() {
                int readSamples = 0;
                while ( playing) {
                    if(decoder!=null){
                        if((readSamples = decoder.readSamples(samples, 0,samples.length))<=0){
                            decoder.dispose();
                            decoder = new Mpg123Decoder(externalFile);
                            playing=false;
                        }
                        device.writeSamples(samples, 0, readSamples);
                    }
                }
            }
        });
        playbackThread.setDaemon(true);
        playbackThread.start();
    }
    
    public void stop(){
        playing=false;
        decoder.dispose();
    }
    public void setVolume(float vol){
        device.setVolume(vol);
    }
    public void setSpeed(float speed){
        device.setSpeed(speed);
    }
    

    }

    Where to get the audio extension? (AudioDevice需要)

    音频扩展似乎已被弃用,并且容易找到 jar ,我上传了它们here,它的旧版本但应该工作得很好 .

    Easier way?

    如果您的游戏只打算在桌面上运行,那么桌面上的libgdx音乐类再次依赖于OpenAL,它可以提供播放音高的功能,因此您只需要编辑音乐界面(桌面上的OpenALMusic)而不是不幸的是,因为dawez说Android上的Music类依赖于MediaPlayer而不是给我们提供音高变换选项,所以AudioDevice并通过样本事物得出整个播放样本 .

    Conclusion :这种方法对我来说似乎并不好看,如果你的游戏真的需要音高的东西,没有它就没有意义,那就去吧,否则它只是为了这么小的细节而付出太大的努力 .

  • 6

    看来你 cannot 改变了Android中音乐的音高 .

    要在libgdx中播放音乐,请参阅界面音乐:

    public interface Music extends Disposable {
    

    这是通过实现的

    package com.badlogic.gdx.backends.android;
    public class AndroidMusic implements Music, MediaPlayer.OnCompletionListener {
            private MediaPlayer player;
    

    您对播放器对象感兴趣 . 那是 MediaPlayer 的类型

    package android.media;
    public class MediaPlayer {
    

    所以现在问题归结为android是否能够支持 MediaPlayer 类的投球 . 简答回答,答案很长:Speed Control of MediaPlayer in Android

    您可以使用的解决方法是使用 SoundPool ,即使速度很慢,也可以在用户加载屏幕时启动加载 . 否则你可以试着将音乐文件分成块并加载它们,因为你仍然使用 SoundPool . 因此,当当前部件即将结束时,您会执行类似延迟加载的操作 .

    如果您设法找到合适的解决方案,请发布相关代码!

  • 1

    随着Android 6.0(API级别23)的发布,可以将“PlaybackParams”添加到MediaPlayer . 这些包括播放速度和音高等 .

相关问题