如何为Android(Java)编写简单的音序器

时间:2011-10-19 15:17:11

标签: java android audio

我想做什么:

我想为Android编写一个非常简单的音乐音序器。但我从未在Android或Java上使用音频。

应用程序应该做什么:

  • 播放样本(WAVE / OGG文件)
  • 同时播放多个音频通道(例如小号和长笛应同时播放,最多可播放10个乐器)
  • 更改样本的音高(例如小号WAVE文件必须以正常音高(c4)和低音高/高音高(e2 / g6)等播放)

这是应用程序通常应该能够做的事情。

我需要哪些组件?普通的媒体播放器(AudioManager?)不起作用,对吗?

已经有一些应用程序可以满足我的需求:

  • 适用于iOS的FingerBeat
  • 适用于iOS的FL Studio Mobile
  • 适用于Android的Uloops Studio

提前感谢您的帮助!

5 个答案:

答案 0 :(得分:6)

Android的开源智能节拍器非常简单,名为SoundFuse。他们在页面上有描述和截图。

Here是github存储库。

答案 1 :(得分:2)

您没有一个简单的要求,而是三个非常不同的要求。

  1. 在javax.sound.sampled中的类的帮助下,JRE应该支持播放WAV,jsut需要一些代码来连接它(不太确定android)。

  2. 开箱即用不支持播放OGG。 OGG有一个名为jOrbis的开源实现,请参阅他们的web site。同样,这可能需要一些连接代码才能挂钩到您的应用程序中。

  3. 对于音序器,您可以只使用MIDI。同样它应该由JRE支持,如果它不在您的平台上,您可以使用Gervill - 纯Java MIDI音序器(Project web site)。

  4. 还有一个ModPlayer可以播放好的旧Soundtracker和其他一些。如果你知道Soundtracker或Screamtracker模块格式(古代格式,但网上仍然有描述),这也可以被滥用为某种类型的音序器。可以找到包含来源的玩家here。跟踪器格式并不是那么古老,当今的一些游戏引擎仍在使用它们。

  5. 如果你真的想要,你可以自己编写序列器,如果有javax.sound.sampled那么基本的东西。它只需要一些关于数字声音的基本知识和大量的接线代码。

  6. 所有没有单一的解决方案,你必须从免费提供的构建模块中将自己拼接在一起。

答案 2 :(得分:2)

我无法提供完整的答案,但我会指出正确的方向。

Android确实支持.wav和.ogg解码。根据:http://developer.android.com/guide/appendix/media-formats.html

我没有任何音频方面的经验,但你最好的选择似乎是SoundPool类,它允许你调整音高和音量,它似乎能够同时播放多个声音:“注意调用播放( )如果超过最大活动流数,可能会导致另一个声音停止播放。“ http://developer.android.com/reference/android/media/SoundPool.html

还有一个MediaPlayer类,但这是为了更简单的使用。我不认为它允许音高控制。

答案 3 :(得分:2)

我为我的应用程序制作了类似的东西(播放长号样本)。经过大量的体验,我发现最好的解决方案是使用AudioTrack。 看看我的源代码: http://code.google.com/p/trombonino/source/browse/trunk/src/com/trombonino

特别是

http://code.google.com/p/trombonino/source/browse/trunk/src/com/trombonino/Trombone.java http://code.google.com/p/trombonino/source/browse/trunk/src/com/trombonino/WavFile.java

答案 4 :(得分:1)

您在Android系统上的计时有问题。为了避免您的sequencer线程被垃圾回收中断,您可能需要使用ndk以本机编写序列器。

播放声音也可能最好使用ndk。

查看https://code.google.com/p/high-performance-audio/

在上面的Soundfuse示例中,sequencer使用SystemClock.sleep(),这绝不是一个好主意。检查Why using System.Threading.Thread.Sleep() is a bad practice?

意识到这个问题真的很老但无论如何都会回答它,因为没有回答提到NDK。