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];
として解放しておくことを忘れずに。