Libgdx,改变音乐的音调

时间:2014-10-25 21:58:46

标签: android libgdx

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

libgdx的Music类不允许更改声音的音高,我尝试使用Sound类代替Music来播放我的音乐,但它非常加载文件时速度慢(5 mb文件为5秒,在桌面上!)。

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

3 个答案:

答案 0 :(得分:7)

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

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

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

1)编辑gdx项目的com.badlogic.gdx.audio包中的AudioDevice.java

在界面

中添加以下代码
public void setSpeed(float val);

2)编辑gdx-backend-android项目的com.badlogic.gdx.backends.android包中的AndroidAudioDevice.java

AudioDevice类的Android端依赖于Android sdk的AudioTrack类,此类具有setPlaybackRate(..)方法。

在类

中添加以下代码
@Override
public void setSpeed (float speed) {
    track.setPlaybackRate((int)(track.getSampleRate()*speed));
}

3)编辑gdx-backend-lwjgl项目的com.badlogic.gdx.backends.lwjgl.audio包中的OpenALAudioDevice.java

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

在类

中添加以下内容
@Override
public void setSpeed (float speed) {
    alSourcef(sourceID, AL_PITCH, speed);
}

4)播放音频

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

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);
}

}

从哪里获得音频扩展?(AudioDevice需要)

音频扩展程序似乎已被弃用,并且无法轻易找到jars,我已将它们上传here,这是一个旧版本,但应该可以正常工作。

更轻松?

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

结论:这种方法对我来说似乎不太好看,如果你的游戏真的需要投球的东西,没有它就没有意义,那就去吧,否则它只是太费劲了一个小细节。

答案 1 :(得分:1)

您似乎无法更改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 时加载它们。因此,当当前部件即将结束时,您会执行类似延迟加载的操作。

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

答案 2 :(得分:1)

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