40
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

[vDSP][信号処理]オーディオ・音声分析への道1

オーディオ・音声分析への道 その1

XcodeとvDSPで行うオーディオ、音声分析について淡々と書いていきます。
言語はCでいきたいと思います。

vDSPはAppleが提供する信号処理ライブラリです。Accelerate.FrameworkとしてXcodeと共にインストールされています。Intel Macはもちろん、iPhoneやIPad用のアプリ開発にも使える便利な代物です。

さて、この「オーディオ・音声分析への道 」はとても単純な配列計算から、FFTを使用した信号処理法、音の性質の分析法、はたまたケプストラムなど専門的な所迄、目指してがんばりたいと思います。

まず、その1では、Xcodeのセットアップからやりたいと思います。

その1 Xcodeを起動する。

当方、Xcode 5.1.1を使用しております。
MacOSはMaverix です。

すると、下の様な画面が出てきますので、左メニューのOS X/Applicationを選択し、Command Line Toolを選択します。

vDSPXcode01.jpg

選択すると、プロジェクトに名前をつけて保存する画面になります。

vDSPXcode02.jpg

ここでは、vDSP_01と名前をつけて保存します。
適当なディレクトリに保存してくださいませ。

こんな感じになります。

vDSPXcode03.jpg

その2 Xcodeを設定する。

必要なFramework等を読み込んで、プロジェクトの準備を行います。

vDSPXcode04.jpg

左のファイルメニューのvDSP_01をクリックし、Build Phaseを選択。
この中の上から三番目、Link Binary With Librariesの灰色の三角ボタンをクリックします。
そうするとライブラリのリスト(未だ何も追加されていない)が現れます。

ここで、+ボタンをクリックしてFrameworkを追加します。

vDSPXcode05.jpg

+ボタンを押すと、Frameworkのリストが表示されます。
このリストの一番上に、Accelerate.frameworkという物があります。これを追加するとvDSPが使用できるようになります。

追加された図です。
vDSPXcode06.jpg

では、この中のmain.cにプログラムを書いていきましょう。
その前にこのままビルドしてみます。

するとコンソールに"Hello World"と表示されます。
これでOK。です。

その3 プログラムを書く

さて、少し丁寧に解説して参りましたが、ここからは飛ばしていきます。
C言語はやった事ある前提でいきます。

vDSPは信号処理用に作られたライブラリなので、配列演算の関数がいくつか用意されています。
今回はそれを使用して、おしまいです。

まず、Accelerate.hをインクルードします。

main.c
#include<Accelerate/Accelerate.h>

次に、input配列2つと、演算結果を格納するoutput配列を1つ作ります。

main.c
int input1[8] = {1,2,3,4,5,6,7,8};    
int input2[8] = {11,12,13,14,15,16,17,18}; 
int output[8];

まず最初に、このinput配列2つを足し合わせてみたいと思います。

main.c
vDSP_vaddi(input1,1,input2,1,output,1,8);

vDSP_vaddは二つの配列の加算処理を行います。
AppleのvDSP Referenceによれば、

main.c
void vDSP_vadd (
   const float __vDSP_input1[],
   vDSP_Stride __vDSP_stride1,
   const float __vDSP_input2[],
   vDSP_Stride __vDSP_stride2,
   float __vDSP_result[],
   vDSP_Stride __vDSP_strideResult,
   vDSP_Length __vDSP_size
);

となっており、つまり

main.c
void vDSP_vadd (
   const float __vDSP_input1[], // インプット1 配列
   vDSP_Stride __vDSP_stride1, // インプット1のストライド (他のインプットに対する長さ = 1)
   const float __vDSP_input2[], // インプット2 配列
   vDSP_Stride __vDSP_stride2, // インプット2のストライド (上に同じ)
   float __vDSP_result[], // アウトプット 配列
   vDSP_Stride __vDSP_strideResult, // アウトプットのストライド(上に同じ)
   vDSP_Length __vDSP_size // 配列のサイズ
);  

となります。
すべての配列が同じ長さで、計算するデータ数も全て同じですので、この場合ストライドは全て1を入れます。
このReferenceはfloat型になっていますが、vDSPには

main.c
vDSP_vaddi(); // int 
vDSP_vadd(); // float
vDSP_vaddD(); // double 

があります。
今回は配列のデータ型が整数なので、vDSP_vaddi()を使用します。

全体のコードです。

main.c
#include <stdio.h>
#include<Accelerate/Accelerate.h>

int main(int argc, const char * argv[])

{
    int input1[8] = {1,2,3,4,5,6,7,8};
    int input2[8] = {11,12,13,14,15,16,17,18};   
    int output[8];
    vDSP_vaddi(input1,1,input2,1,output,1,8);

    // 結果表示
    int i;
    for(i=0;i<8;i++){
        printf("output[%d] = %d\n",i,output[i]);
    }

    return 0;
}

結果は

result
output[0] = 12
output[1] = 14
output[2] = 16
output[3] = 18
output[4] = 20
output[5] = 22
output[6] = 24
output[7] = 26
Program ended with exit code: 0

float型とdouble型も試してみてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
40
Help us understand the problem. What are the problem?