• Android游戏开发:游戏框架的搭建(2)


    4.音频模块(Audio)

      音频模块编程从来都是一个复杂的话题。这里不打算用到一些高级复杂的音频处理手段,主要是播放一些背景音乐。在书写代码前,让我们了解一下音频的基础知识。

      采样率:定义了每秒从连续信号中提取并组成离散信号的采样个数,采样率越高音质越好,单位用赫兹(Hz)来表示,CD一般是44.1KHz。对于每个采样系统会分配一定存储位(bit数)来表达声波的声波振幅状态,称之为采样分辨率或采样精度,每增加1个bit,表达声波振幅的状态数就翻一翻,并且增加6db的动态范围态,1个2bit的数码音频系统表达千种状态,即12db的动态范围,以此类推。如16bit能够表达65536种状态,24bit可以表达多达16777216种状态。动态范围是指声音从最弱到最强的变化范围,人耳的听觉范围通常是20HZ~20KHZ。高的采样率意味着更多的存储空间。比如60s的声音,采样率8KHz、8bits,大约0.5M,采样率44KHz、16bits,超过5M,普通的3分钟的流行歌曲,将会超过15M。

      为了即不降低质量有不太占据空间,很多比较好的压缩方法被提出来。比如MP3s 和OGGs格式就是网络中比较流行的压缩格式。

      可以看到3min的歌曲占了不少空间。当我们播放游戏的后台音乐时,我们可以把音频流化而不是预先加载到内存。通常背景音乐只有一个,因此只需要到磁盘加载一次即可。

      对于一些短的音效,比如爆炸声和枪的射击声,情况有所不同。这些短的音效经常会同时被调用多次,从磁盘对每个实例流化这些音效不是一个好的办法。幸运的是,短的音效并不占用太多的内存空间,因此只需把这些音效提前读入到内存即可,然后可以直接地同时播放这些音效。

      因此我们的代码需要提供如下功能:

      我们需要一种方法加载音频文件,用于流化播放(Music)和内存播放(Sound),同时提供控制播放功能。

      相应的接口有三个,Audio、Music和Sound,代码如下。

      Audio接口Audio.java

    package com.badlogic.androidgames.framework;

    public interface Audio {
      public Music newMusic(String filename);
      public Sound newSound(String filename);
    }

      Audio接口创建新的Music和 Sound实例。一个Music实例表示一个流音频文件,一个Sound实例表示一个保存在内存中的短的音效。方法 Audio.newMusic()和Audio.newSound()都是以文件名作为参数并抛出IOException以防文件加载失败(例如文件不存在或者文件损坏等情况)。

      Music接口Music.jva

    package com.badlogic.androidgames.framework;

    public interface Music {

      public void play();

      public void stop();

      public void pause();

      public void setLooping(boolean looping);

      public void setVolume(float volume);

      public boolean isPlaying();

      public boolean isStopped();

      public boolean isLooping();

      public void dispose();
    }

      Music接口有点复杂,包含了播放音乐流、暂定和停止、循环播放、音量控制(从0到1的浮点数)方法。当然,里面还有一些getter方法,用来获取当前音乐实例的状态。当我们不再需要Music 实例时, 我们可以销毁它(dispose方法),这会关闭系统资源,即流化的音频文件。

     Sound接口Sound.java

    package com.badlogic.androidgames.framework;

    public interface Sound {

      public void play(float volume);

      public void dispose();

    }

      Sound接口比较简单,只包含play()和dispose()方法。前者以指定的音量为输入参数,我们可以在任何我们需要的时候播放音效。后者在我们不许Sound实例时,我们需要销毁它以释放它占用的内存空间。

    PS: 欢迎关注公众号"Devin说",会不定期更新Java相关技术知识。

  • 相关阅读:
    LeetCode:149_Max Points on a line | 寻找一条直线上最多点的数量 | Hard
    LeetCode: 150_Evaluate Reverse Polish Notation | 分析逆波兰式 | Medium
    LeetCode:151_Reverse Words in a String | 字符串中单词的逆反 | Medium
    Cellular Traffic Offloading
    在word 2010中采用EndNote X7插入引用
    屏幕截图和标记
    A Nice Paper About Mobile Data Offloading
    linux Redhat 6环境上通过源码包安装DRBD 8
    hbase shell中执行list命令报错:ERROR: org.apache.hadoop.hbase.PleaseHoldException: Master is initializing
    如何通过phoenix中查看表的主键信息
  • 原文地址:https://www.cnblogs.com/devinzhang/p/2392069.html
Copyright © 2020-2023  润新知