[[SiioLaboratory]]

iPhoneのアプリケーション開発を行うための、ごくごく簡単なメモです。
iPhoneアプリを開発するための How2iPhoneProgramming をも参考にしてください。


*iPhoneから正弦波を出す方法 [#w0f704d6]

**Audio Toolbox .framework を使う [#h5b8d045]

xcodeで、Audio Toolbox フレームワークを設定しておく。

http://gyazo.com/61baab77ba29820c376c9106c0d67c16.png

次に、以下のクラスを作っておく。

**Sound Player .h [#s8356cd2]

 //
 //  SoundPlayer.h
 //
 //  Created by SIIO Itiro on 11/04/17.
 //  Copyright 2011 __MyCompanyName__. All rights reserved.
 //
 
 #import <Foundation/Foundation.h>
 #import <AudioToolbox/AudioToolbox.h> 
 
 @interface SoundPlayer : NSObject {
 	AudioQueueRef queueRef;
 }
 
 
 -(id)init;
 -(void)start; 
 -(void)pause; 
 -(void)stop; 
 
 @end
 

**Sound Player .m [#j52c1222]

 //
 //  SoundPlayer.m
 //
 //  Created by SIIO Itiro on 11/04/17.
 //  Copyright 2011 __MyCompanyName__. All rights reserved.
 //
 
 #import "SoundPlayer.h"
 
 
 #define SAMPLERATE 44100.0f
 #define FL ((2.0f * 3.14159f) / SAMPLERATE) 
 #define FR ((2.0f * 3.14159f) / SAMPLERATE) 
 #define FRAMECOUNT 1024
 #define NUM_BUFFERS 3
 
 
 
 @implementation SoundPlayer
 
 static void aqCallBack(void *in, AudioQueueRef q, AudioQueueBufferRef qb) { 
 	
 	static int phaseL = 0; 
 	static int phaseR = 0; 
 	
 	short *sinBuffer = (short *)qb->mAudioData; 
 	
     float sampleL = 0.0f; 
     float sampleR = 0.0f; 
 	
 	float amplitude = 1.0f, pitch=100.0f;
 	
 	qb->mAudioDataByteSize = 4 * FRAMECOUNT; 
 	// 1 frame per packet, two shorts per frame = 4 * frames 
 	for(int i = 0; i < ( FRAMECOUNT * 2 ) ; i+=2) {
 		sampleL = (amplitude * sin(pitch * FL * (float)phaseL));
 		sampleR = (amplitude * sin(pitch * FR * (float)phaseR));
 	
 		short sampleIL = (int)(sampleL * 32767.0f); 
 		short sampleIR = (int)(sampleR * 32767.0f); 
 		sinBuffer[i] = sampleIL; 
 		sinBuffer[i+1] = sampleIR; 
 		phaseL++; 
 		phaseR++; 
 	}//end for
 	AudioQueueEnqueueBuffer(q, qb, 0, NULL); 
 	
 } 
 	
 	
 -(id)init { 
 	AudioStreamBasicDescription dataFormat;
     AudioQueueBufferRef buffers[NUM_BUFFERS]; 
 	
 	self = [super init];
 	
 	dataFormat.mSampleRate = SAMPLERATE; 
 	dataFormat.mFormatID = kAudioFormatLinearPCM; 
 	dataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 
 	dataFormat.mBytesPerPacket = 4; 
 	dataFormat.mFramesPerPacket = 1; 
 	dataFormat.mBytesPerFrame = 4; 
 	dataFormat.mChannelsPerFrame = 2; 
 	dataFormat.mBitsPerChannel = 16; 
 
 	AudioQueueNewOutput(&dataFormat, aqCallBack, self, NULL, kCFRunLoopCommonModes, 0, &queueRef); // CFRunLoopGetCurrent() 
 
 	for(int i = 0; i < NUM_BUFFERS; i++) { 
 	
 		UInt32 err = 
 		AudioQueueAllocateBuffer(queueRef, FRAMECOUNT * dataFormat.mBytesPerFrame, &buffers[i]); 
 		if(err) { 
 			NSLog(@"err:%d\n"); 
 		}//end if 
 	
 		aqCallBack(self, queueRef, buffers[i]); //prime buffer 
 	}//end for
 	AudioQueueSetParameter(queueRef, kAudioQueueParam_Volume, 1.0f); 
 
 	return self; 
 	
 } 
 	
 	
 -(void)start { 
 	AudioQueueStart(queueRef, NULL); 
 } 
 
 -(void)pause{
 	AudioQueuePause(queueRef);
 }
 	
 -(void)stop { 
 	AudioQueueStop(queueRef, true); 
 } 
 			
 -(void)dealloc { 
 	AudioQueueDispose(queueRef, true); 
 	[super dealloc]; 
 } 
 	
 
 @end
 
**使い方 [#j92fbff1]

どこかで

 SoundPlayer *sp1;

と定義しておいて、

 sp1 = [[SoundPlayer alloc] init];

としてインスタンス化する。これに対して、

 [sp1 start];

とすれば100kHzの正弦波が再生される。
一方、

 [sp1 pause];

とすれば、再生が停止する。最後に、どこかで、

 [sp1 dealloc];

として解放しておくことを忘れずに。

**参考サイト [#e97c23ef]

-[[http://www.iphonedevsdk.com/forum/iphone-sdk-development/11658-audio-synthesis-using-speakhere-base.html:http://www.iphonedevsdk.com/forum/iphone-sdk-development/11658-audio-synthesis-using-speakhere-base.html]]
&br;ここで紹介されている正弦波発生プログラムを参考に単純化しまし
-[[A simple MacOS X Cocoa CoreAudio demo application. :http://www.audiosynth.com/sinewavedemo.html]]
&br;Mac OS X用のトーンジェネレータプログラム
-[[iPhone アプリで効果音のような短い音を鳴らす方法:http://blog.syuhari.jp/archives/933]]
&br; 30秒以下の音のファイルを鳴らす方法

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS