iPhoneのアプリケーション開発を行うための、ごくごく簡単なメモです。 iPhoneアプリを開発するための How2iPhoneProgramming をも参考にしてください。
xcodeで、Audio Toolbox フレームワークを設定しておく。
次に、以下のクラスを作っておく。
// // 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
// // 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
どこかで
SoundPlayer *sp1;
と定義しておいて、
sp1 = [[SoundPlayer alloc] init];
としてインスタンス化する。これに対して、
[sp1 start];
とすれば100kHzの正弦波が再生される。 一方、
[sp1 pause];
とすれば、再生が停止する。最後に、どこかで、
[sp1 dealloc];
として解放しておくことを忘れずに。