音符起始点检测(音频节奏检测)(2)

原文链接:Onset Detection Part 2: A simple framework

好了,我刚刚为我们的起始点检测入门教程组合了一个简单的框架。它位于 http://code.google.com/p/audio-analysis/ 。要获得代码,你将需要一个SVN客户端,在Windows平台上Tortoise SVN 是相当好的,使用linux平台的人应该知道自己该怎么办 :)。只需从 svn URL http://audio-analysis.googlecode.com/svn/trunk/ 检出该项目,并将其导入Eclipse。现在您已经准备好了,让我们来看看这个“框架”里面都有什么。

第一个类叫作AudioDevice。看起来是这样的

public class AudioDevice
{
   public AudioDevice( );
   public void writeSamples( float[] samples );
}

很简单,不是吗?这将在44100Hz单声道模式下设置一个到主声卡的连接。只需调用构造函数。如果它不能安装(setup)硬件,它将抛出一个异常,但“这绝不应该发生”(TM)。要将PCM数据输出到音频设备,请调用 AudioDevice.writeSamples 并传入你的包含 44100Hz 单声道 PCM样本的浮点数组。

我写了一个小例子,它将产生一个440Hz的正弦波,并输出到音频设备。它是这样的:

public class NoteGenerator 
{
   public static void main( String[] argv ) throws Exception
   {
      final float frequency = 880; // 440Hz for note A
      float increment = (float)(2*Math.PI) * frequency / 44100; // angular increment for each sample
      float angle = 0;
      AudioDevice device = new AudioDevice( );
      float samples[] = new float[1024];
		
      while( true )
      {
         for( int i = 0; i < samples.length; i++ )
         {
            samples[i] = (float)Math.sin( angle );
            angle += increment;
         }
			
         device.writeSamples( samples );
      }
   }
}

它基本上是本系列第1部分中代码片段的重写版本。在每个循环迭代中,我们生成下一个1024个正弦波样本,并将其提供给音频设备。稍微修改一下这段代码,比如改变正弦波的频率。例如,如果你把频率加倍,你可以得到高八度的同一个音符。反之亦然。要停止程序,您必须在Eclipse中单击stop按钮来终止它。一个合适的GUI对于这样简单的例子来说有点多余。您可以在 com.badlogic.audio.samples 包中找到源代码。

我提供给您的第二个类是一个Wave文件解码器。使用这个类,您可以读取16位单声道/立体声的Wave文件,采样率为44100Hz。该解码器支持其他一些格式/采样率,但是为了简单起见,我只支持上面提到的配置。实现所有这些功能的类称为 WaveDecoder 。它将把PCM数据从Wave文件转换为flie上的32位浮点采样样本。以下是该类的签名:

public class WaveDecoder
{ 
   public WaveDecoder( InputStream stream ) throws Exception;
   public int readSamples( float[] samples );
}

又相当简单。在构造函数中,您传递InputStream,从那里读取Wave文件。如果发生错误,将抛出异常。正确实例化该类之后,可以通过调用 WaveDecoder.readSamples() Wave文件中读取采样样本。该方法将尝试从Wave文件中读取与传入的samples数组中的元素个数相同的样本。它将返回实际读取的样本数量。如果Wave文件是立体声的,则立体声样本将被均值处理为本系列第1部分中解释的单声道样本。如果方法返回0,您就知道已经到达流的末尾,或者发生了错误。下面是一个简单的例子,如何使用波解码器结合音频设备入从一个Wave文件输出声音:

public class WaveOutput 
{
   public static void main( String[] argv ) throws Exception
   {
      AudioDevice device = new AudioDevice( );
      WaveDecoder decoder = new WaveDecoder( new FileInputStream( "samples/sample.wav" ) );
      float[] samples = new float[1024];
                
      while( decoder.readSamples( samples ) > 0 )
         device.writeSamples( samples );
   }
}

我们首先构造音频设备和波解码器,以及一个浮点数组,其中包含从Wave文件中读取的样本。在每个循环迭代中,我们尝试读取1024个样本(样本数组的长度)并将这些样本写入音频设备。就是这样。声音编程真的很简单。示例的代码可以在包 com.badlogic.audio.samples 中找到。接下来你就可以开始,盘它。例如,您可以改变采样的振幅,例如,在将每个采样写入音频设备之前,将每个采样的响度乘以0.5,从而将响度减半。

我将向这个项目添加一些helper类,以可视化我们在本系列中处理/生成的数据。我们还将通过一些漂亮的分析类来扩展这个项目,这些类将允许我们进行适当的节拍检测(can you say Fast Fourier Transform?(快速傅里叶变换))你会很惊奇它是多么容易做简单的节拍检测?。

结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值