[[SiioLaboratory]] #author("2022-01-13T19:14:49+09:00","","") 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秒以下の音のファイルを鳴らす方法