How to use CARingBuffer class in an iOS (iPhone, iPad) project? - iphone

I'm currently trying to create an iOS audio project and I need to use the CARingBuffer class available in the Extras/CoreAudio/PublicUtility folder of XCode.
The problem is when I include the CARingBuffer.h in the header of my viewController and I declare a CARingBuffer object, I receive 4 compile errors.
To reproduce my problem it's pretty simple. Just create a new view based application and try to #include "CARingBuffer.h" in the header of your viewController.
Here's the content of my testViewController.h :
#import <UIKit/UIKit.h>
#include "CARingBuffer.h"
#interface testViewController : UIViewController {
}
#end
Here's the content of my testViewController.m :
#import "testViewController.h"
#implementation testViewController
- (void)dealloc
{
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
*/
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Bellow the 4 compile errors located (strangely) in the CARingBuffer according to XCode 4 :
1) Initializer element is not a constant on line :
const UInt32 kGeneralRingTimeBoundsQueueMask = kGeneralRingTimeBoundsQueueSize - 1;
2) Expected ';' after top level declarator, Expected '='... or 'atribute' before 'CARingBuffer' :
class CARingBuffer {
3) Initializer element is not a constant on line :
const UInt32 kGeneralRingTimeBoundsQueueMask = kGeneralRingTimeBoundsQueueSize - 1;
4) Expected ';' after top level declarator, Expected '='... or 'atribute' before 'CARingBuffer' :
class CARingBuffer {
Thanks in advance for your help.

Also take a look at this alternative

You need to rename the class that you are including the ring buffer in to be a .mm file.
This tells the compiler to use objective c++ .

You need change your testViewController.m to testViewController.mm because CARingBuffer is c++ class.
About how to use it, here is an extend of CARingBuffer : CARingBufferEx
//header file
#include "CARingBuffer.h"
class CARingBufferEx : public CARingBuffer {
public:
CARingBufferEx();
~CARingBufferEx();
CARingBufferError Store(const AudioBufferList *abl, UInt32 nFrames, SampleTime frameNumber);
CARingBufferError Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime frameNumber);
private:
SInt64 firstInputSampleTime;
SInt64 firstOutputSampleTime;
SInt64 offset;
};
//Class
#include "CARingBufferEx.h"
#include "stdio.h"
CARingBufferEx::CARingBufferEx():firstInputSampleTime(-1), firstOutputSampleTime(-1), offset(0) {
}
CARingBufferEx::~CARingBufferEx() {
}
CARingBufferError CARingBufferEx::Store(const AudioBufferList *abl, UInt32 nFrames, SampleTime frameNumber) {
if (firstInputSampleTime < 0) {
firstInputSampleTime = frameNumber;
if (firstOutputSampleTime > 0 && offset == 0) {
offset = firstInputSampleTime - firstOutputSampleTime;
}
}
return CARingBuffer::Store(abl, nFrames, frameNumber);
}
CARingBufferError CARingBufferEx::Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime frameNumber) {
if (firstOutputSampleTime < 0) {
firstOutputSampleTime = frameNumber;
if (firstInputSampleTime > 0 && offset == 0) {
offset = firstInputSampleTime - firstOutputSampleTime;
}
}
return CARingBuffer::Fetch(abl, nFrames, frameNumber + offset);
}
Usage:
CARingBufferEx* _musicMixerRingBuffer;
_musicMixerRingBuffer = new CARingBufferEx();
_musicMixerRingBuffer->Allocate(2, sizeof(AudioUnitSampleType), 1024 * 50);
//1024 is length for one package. and 50 means this buffer contains 50 packages at most.
//store
//ioData is AudioBufferList ,inTimeStamp is AudioTimeStamp
musicMixerRingBuffer->Store(ioData, inNumberFrames, inTimeStamp->mSampleTime);
//Fetch
musicMixerRingBuffer->Fetch(ioData, inNumberFrames, inTimeStamp->mSampleTime);

Related

run time catch method [duplicate]

I am developing an Objective-C application, and what I want to do, is something like the following:
+-----------------+ +---------------+
| Some Object | <---------- | Synchronize |
|(Not Thread Safe)| | Proxy |
+-----------------+ / +---------------+
/
/ Intercepts [someobject getCount]
/ #synchronize (someObject)
/
[someObject getCount] /
+----------------------+
| Some Calling Object |
+----------------------+
What I've asking is, how can I create an object in objective-c, that intercepts messages sent to another object, in order to perform code before the message is sent to that object.
Some things that I think will not work:
Categories (I need this to only happen for certain instances of a class)
Rewriting the object (I don't have access to the source of the object)
Method swizzling (once again, this need to only happen for certain instances of a class)
You would implement an NSProxy that forwards messages to your non-thread-safe object.
Here is a nice writeup of message forwarding in Objective-C, and here is Apple's documentation.
To handle thread safety, it depends on what you need. If your non-thread-safe object must run on a specific thread then you can use a NSRunLoop on said thread to serialize messages to that object.
Here is an example of using NSInvocation in conjunction with NSRunLoop. In that example they're using performSelector:withObject:afterDelay: but to use it with performSelector:onThread:withObject:waitUntilDone: would be very similar.
Otherwise, just use a single NSRecursiveLock in your proxy.
If you know exactly what instances should have the behavior you are trying to achieve you can go with method swizzling and call the base implementation if the instance is not the one you are looking for.
You can have a global shared object that lists the "interesting" instances and use it in the swizzling implementation whether you have to call the base one or your custom one.
So, I bit the bullet, and decided to make my own proxy class. To subclass, you simply override the 'forwardInvocation:' message, and you call any code you need there, before calling [super forwardInvocation:]. Please not this will NOT work with vardic methods, as NSInvocation doesn't work with vardic methods.
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/objc.h>
#import <objc/message.h>
#interface RJProxy : NSObject {
#private
NSObject *target;
}
#property(readwrite, retain) NSObject *target;
-(NSObject *) getTarget;
#end
#implementation RJProxy
#synthesize target;
-(NSMethodSignature *) methodSignatureForSelector:(SEL)aSelector
{
if (objc_getAssociatedObject(self, "isProxy"))
{
IMP NSObjectImp = [NSObject instanceMethodForSelector:#selector(methodSignatureForSelector:)];
NSMethodSignature *methodSignature = (NSMethodSignature *) NSObjectImp(self, #selector(methodSignatureForSelector:), aSelector);
if (methodSignature)
return methodSignature;
return [target methodSignatureForSelector:aSelector];
}
else
{
Class subClass = self->isa;
#try {
self->isa = objc_getAssociatedObject(self, "realSuperclass");
return [super methodSignatureForSelector:aSelector];
}
#finally {
self->isa = subClass;
}
}
}
-(void) forwardInvocation:(NSInvocation *)anInvocation
{
if (objc_getAssociatedObject(self, "isProxy"))
{
Class subClass = target->isa;
target->isa = objc_getAssociatedObject(self, "realSuperclass");
[anInvocation invokeWithTarget:target];
target->isa = subClass;
}
else
{
Class realSuperclass = objc_getAssociatedObject(self, "realSuperclass");
Class subclass = self->isa;
self->isa = realSuperclass;
if ([self respondsToSelector:[anInvocation selector]])
{
[anInvocation invokeWithTarget:self];
}
else
{
[self doesNotRecognizeSelector:[anInvocation selector]];
}
self->isa = subclass;
}
}
-(NSObject *) getTarget
{
if (objc_getAssociatedObject(self, "isProxy"))
{
return target;
}
return self;
}
#end
BOOL object_setProxy(NSObject *object, RJProxy *proxy);
BOOL object_setProxy(NSObject *object, RJProxy *proxy)
{
proxy.target = object;
Class objectClass = object_getClass(object);
Class objectSub = objc_allocateClassPair(objectClass, [[NSString stringWithFormat:#"%s_sub%i", class_getName(objectClass), objc_getAssociatedObject(objectClass, "subclassTimes")] UTF8String], 0);
objc_setAssociatedObject(objectClass, "subclassTimes", (id) ((int) objc_getAssociatedObject(objectClass, "subclassTimes") + 1), OBJC_ASSOCIATION_ASSIGN);
objc_registerClassPair(objectSub);
Class proxyClass = object_getClass(proxy);
Class proxySub = objc_allocateClassPair(proxyClass, [[NSString stringWithFormat:#"%s_sub%i", class_getName(proxyClass), objc_getAssociatedObject(proxyClass, "subclassTimes")] UTF8String], 0);
objc_setAssociatedObject(proxyClass, "subclassTimes", (id) ((int) objc_getAssociatedObject(proxyClass, "subclassTimes") + 1), OBJC_ASSOCIATION_ASSIGN);
objc_registerClassPair(proxySub);
object_setClass(object, proxySub);
object_setClass(proxy, proxySub);
objc_setAssociatedObject(object, "isProxy", (id) NO, OBJC_ASSOCIATION_ASSIGN);
objc_setAssociatedObject(proxy, "isProxy", (id) YES, OBJC_ASSOCIATION_ASSIGN);
objc_setAssociatedObject(object, "realSuperclass", objectClass, OBJC_ASSOCIATION_ASSIGN);
objc_setAssociatedObject(proxy, "realSuperclass", proxyClass, OBJC_ASSOCIATION_ASSIGN);
return NO;
}
#interface SynchronizeProxy : RJProxy
#end
#implementation SynchronizeProxy
-(void) forwardInvocation:(NSInvocation *)anInvocation {
#synchronized ([self getTarget])
{
[super forwardInvocation:anInvocation];
}
}
#end
int main (int argc, const char * argv[])
{
#autoreleasepool {
NSArray *arrayToSynchronize = [NSArray arrayWithObjects:#"This, is, a, test!", nil];
SynchronizeProxy *myProxy = [SynchronizeProxy new];
object_setProxy(arrayToSynchronize, myProxy);
// now all calls will be synchronized!
NSLog(#"Array at address 0x%X with count of %lu, and Objects %# ", (unsigned) arrayToSynchronize, [arrayToSynchronize count], arrayToSynchronize);
[myProxy release];
[arrayToSynchronize release];
}
return 0;
}

Rewrite C++ code into Objective C

I got some C++ Sourcecode that I would like to rewrite into Objective C.
It would help me alot if someone could write me a header file for this Code. When I get the Headerfile I would be able to rewrite the rest of the Sourcecode.
It would be very nice if someone could help me please.
Thanks
I will poste the sourcecode here:
#include <stdlib.h>
#include <iostream.h>
#define STATES 5
int transitionTable[STATES][STATES];
// function declarations:
double randfloat (void);
int chooseNextEventFromTable (int current, int table[STATES][STATES]);
int chooseNextEventFromTransitionTablee (int currentState);
void setTable (int value, int table[STATES][STATES]);
//////////////////////////////////////////////////////////////////////////
int main(void) {
int i;
// for demo purposes:
transitionTable[0][0] = 0;
transitionTable[0][1] = 20;
transitionTable[0][2] = 30;
transitionTable[0][3] = 50;
transitionTable[0][4] = 0;
transitionTable[1][0] = 35;
transitionTable[1][1] = 25;
transitionTable[1][2] = 20;
transitionTable[1][3] = 30;
transitionTable[1][4] = 0;
transitionTable[2][0] = 70;
transitionTable[2][1] = 0;
transitionTable[2][2] = 15;
transitionTable[2][3] = 0;
transitionTable[2][4] = 15;
transitionTable[3][0] = 0;
transitionTable[3][1] = 25;
transitionTable[3][2] = 25;
transitionTable[3][3] = 0;
transitionTable[3][4] = 50;
transitionTable[4][0] = 13;
transitionTable[4][1] = 17;
transitionTable[4][2] = 22;
transitionTable[4][3] = 48;
transitionTable[4][4] = 0;
int currentState = 0;
for (i=0; i<10; i++) {
std::cout << currentState << " ";
currentState = chooseNextEventFromTransitionTablee(currentState);
}
return 0;
};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// chooseNextEventFromTransitionTable -- choose the next note.
//
int chooseNextEventFromTransitionTablee(int currentState) {
int targetSum = 0;
int sum = 0;
int targetNote = 0;
int totalevents = 0;
int i;
currentState = currentState % STATES; // remove any octave value
for (i=0; i<STATES; i++) {
totalevents += transitionTable[currentState][i];
}
targetSum = (int)(randfloat() * totalevents + 0.5);
while (targetNote < STATES &&
sum+transitionTable[currentState][targetNote] < targetSum) {
sum += transitionTable[currentState][targetNote];
targetNote++;
}
return targetNote;
}
//////////////////////////////
//
// randfloat -- returns a random number between 0.0 and 1.0.
//
double randfloat(void) {
return (double)rand()/RAND_MAX;
}
//////////////////////////////
//
// setTable -- set all values in the transition table to the given value.
//
void setTable(int value, int table[STATES][STATES]) {
int i, j;
for (i=0; i<STATES; i++) {
for (j=0; j<STATES; j++) {
table[i][j] = value;
}
}
}
Update
I'm not only compiling the header file there is another file i'm compiling too
SourceCode:
//
// markovThreadsChainsViewController.m
// markovThreadsChains
//
// Created by Philippe Mokrzycki on 15.01.11.
// Copyright 2011 TGM. All rights reserved.
//
#import "markovThreadsChainsViewController.h"
#import "markov.h"
//#import "markovChainOC.h"
#implementation markovThreadsChainsViewController
#synthesize mcValueLabel, threadStartGenerateButton, threadStopGenerateButton;
- (IBAction) startThreadGen:(UIButton *)sender{
threadStopGenerateButton.hidden=NO;
threadStartGenerateButton.hidden=YES;
mcValueLabel.text = #"0";
currentState=0;
// markovChainOC *mCobc = [[markovChainOC alloc]init];
// [mCobc setCurrentState:0];
[NSThread detachNewThreadSelector:#selector(startThreading) toTarget:self withObject:nil];
}
- (IBAction) stopThreadGen:(UIButton *)sender{
threadStopGenerateButton.hidden=YES;
threadStartGenerateButton.hidden=NO;
[NSThread detachNewThreadSelector:#selector(stopThreading) toTarget:self withObject:nil];
}
- (void) startThreading {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
[NSThread sleepForTimeInterval:3];
[self performSelectorOnMainThread:#selector(markovGen) withObject:nil waitUntilDone:NO];
[pool release];
}
- (void) stopThreading {
[NSThread cancelPreviousPerformRequestsWithTarget:self];
}
- (void)markovGen{
transitionTable[0][0] = 25;
transitionTable[0][1] = 25;
transitionTable[1][0] = 25;
transitionTable[1][1] = 25;
// int actualValue = [mCobc getCurrentState];
int actualValue = currentState;
mcValueLabel.text = [NSString stringWithFormat:#"%", actualValue];
currentState = chooseNextEventFromTransitionTablee(currentState);
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(markovGen) userInfo:nil repeats:NO];
}
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[mcValueLabel release];
[threadStartGenerateButton release];
[threadStopGenerateButton release];
// [mCobc release];
[super dealloc];
}
#end
This code has nothing object-oriented in it at all. Just change iostream.h to stdio.h, and cout to printf. Then it's a regular C program.
Just put these lines into a header file, and you should be able to include the header and call the functions from any other Objective-C or C source file.
(To support C++ also, you may need to put extern "C" { ... } around them, unless you are compiling everything as C++ or Objective-C++.)
#pragma once
#define STATES 5
int transitionTable[STATES][STATES];
// function declarations:
double randfloat (void);
int chooseNextEventFromTable (int current, int table[STATES][STATES]);
int chooseNextEventFromTransitionTablee (int currentState);
void setTable (int value, int table[STATES][STATES]);
More detail:
To use these functions from another class, you'll need the following files in your project:
markov.h (or whatever you decide to call it), containing the lines above.
markov.c (or whatever you decide to call it), containing the other stuff from your original source file, except for the main function, which you should remove
Then, your other files that use the functions should have an #include "markov.h" line, and then you should be able to call them.
If you are getting linker errors about missing functions, it means that you are not compiling markov.c as part of the project, or there are some options that are causing the function names to not match properly.

Problem initializing an object with init in Objective-C

I have an object that i intalize it's propertis with call to an init function, it works fine,
when i tried to add another object and intalize it the first object didn't get the properites, how do i initalize it to more then one object with diffrent or the same properties?
- (void)viewDidLoad {
pic1 = [[peopleAccel alloc] init];
}
Class peopleAccel:
- (id) init
{
self = [super init];
if (self != nil) {
position = CGPointMake(100.0, 100.0);
velocity = CGPointMake(4.0, 4.0);
radius = 40.0;
bounce = -0.1f;
gravity = 0.5f;
dragging = NO;
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
acceleratedGravity = CGPointMake(0.0, gravity);
}
return self;
}
I see a problem with setting the delegate of sharedAccelerometer. Only one object can be a delegate of another object at a time. So you should create only one peopleAccel object.
EDIT:
If you need to send accelerometer events to more than one object, you can create a specific delegate object in charge of receiving accelerometer events and broadcasting them to your several peopleAccel objects via notifications. See this question for some hints: NSNotificationCenter vs delegation?
Create a proxy so multiple objects can receive accelerometer events.
Whether you should do this or use NSNotificationCenter is debatable and there are two camps, but personally I would use this approach. NSNotificationCenter has to check string names to recognise event type; this kind of approach could be ever so slightly faster especially with a bit more optimisation. A bit more typing but I would say also easier for someone else to follow.
Something like this...
/* PLUMBING */
/* in headers */
#protocol MyAccelSubDelegate
-(void)accelerometer:(UIAccelerometer*)accelerometer
didAccelerate:(UIAcceleration*)acceleration;
#end
#interface MyAccelSubDelegateProxy : NSObject <UIAccelerometerDelegate> {
NSMutableArray subDelegates;
}
-(id)init;
-dealloc;
-(void)addSubDelegate:(id<MyAccelSubDelegate>)subDelegate;
-(void)removeSubDelegate:(id<MyAccelSubDelegate>)subDelegate;
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:
(UIAcceleration *)acceleration;
#end
/* in .m file */
#implementation MyAccelSubDelegateProxy
-(id)init { self = [super init];
if (self!=nil) subDelegates = [[NSMutableArray alloc] init]; return self; }
-dealloc { [subDelegates release]; }
-(void)addSubDelegate:(id<MyAccelSubDelegate>)subDelegate {
[subDelegates insertObject:subDelegate atIndex:subDelegates.count]; }
-(void)removeSubDelegate:(id<MyAccelSubDelegate>)subDelegate {
for (int c=0; c < subDelegates.count; c++) {
id<MyAccelSubDelegate> item = [subDelegates objectAtIndex:c];
if (item==subDelegate) { [subDelegates removeObjectAtIndex:c];
c--; continue; }
}
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:
(UIAcceleration *)acceleration {
for (int c=0; c < subDelegates.count; c++)
[((id<MyAccelSubDelegate>)[subDelegates objectAtIndex:c])
accelerometer:accelerometer didAccelerate:acceleration];
}
#end
/* SOMEWHERE IN MAIN APPLICATION FLOW STARTUP */
accelProxy = [[MyAccelSubDelegateProxy alloc] init];
[UIAccelerometer sharedAcclerometer].delegate = accelProxy;
[UIAccelerometer sharedAcclerometer].updateInterval = 0.100; // for example
/* TO ADD A SUBDELEGATE */
[accelProxy addSubDelegate:obj];
/* TO REMOVE A SUBDELEGATE */
[accelProxy removeSubDelegate:obj];
/* SOMEWHERE IN MAIN APPLICATION SHUTDOWN */
[UIAccelerometer sharedAcclerometer].delegate = nil;
[accelProxy release];

Playing audio on the iPhone decoded by a third-party library

The third-party library generates sequential buffers of 16-bit signed stereo samples of any desired size. I can't figure out which framework/functions to use to play from these buffers. I've been working off the example in this answer using AudioQueue but it's obviously incomplete in ways I can't resolve (local variables are used as if they are object members, undeclared variables, etc).
The code in Apple's SpeakHere example project only shows how to use AudioQueue to play audio from a file. Can someone point me in the right direction?
Figured it out. Here's a simple, complete and working white noise generator using AudioQueue created from the Window-based Application project template.
StaticAppDelegate.h:
// StaticAppDelegate.h
#import <UIKit/UIKit.h>
// STATIC ADDITIONS
// Add > Existing Frameworks... > AudioToolbox.framework to your Target
#import <AudioToolbox/AudioToolbox.h>
// END STATIC ADDITIONS
#interface StaticAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
// STATIC ADDITIONS
- (void)startStatic;
- (void)handleBufferCompleteForQueue:(AudioQueueRef)inAQ
buffer:(AudioQueueBufferRef)inBuffer;
// END STATIC ADDITIONS
#end
StaticAppDelegate.m:
// StaticAppDelegate.m
#import "StaticAppDelegate.h"
// STATIC ADDITIONS
#define kNumberBuffers 4
#define kBufferSize 2048
// AudioQueue callback
void AQOutputCallback(
void *inData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer
)
{
StaticAppDelegate *staticApp = (StaticAppDelegate *)inData;
[staticApp handleBufferCompleteForQueue:inAQ buffer:inBuffer];
}
// END STATIC ADDITIONS
#implementation StaticAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
[window makeKeyAndVisible];
// STATIC ADDITIONS
[self startStatic];
// END STATIC ADDITIONS
}
- (void)dealloc {
[window release];
[super dealloc];
}
// STATIC ADDITIONS
- (void)startStatic
{
srandom(time(NULL));
// initiate audio session
AudioSessionInitialize(NULL, NULL, NULL, NULL);
UInt32 category = kAudioSessionCategory_MediaPlayback; // plays through sleep lock and silent switch
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);
AudioSessionSetActive(true);
// following is modified from http://stackoverflow.com/questions/1710133/playing-generated-audio-on-an-iphone
// setup queue
AudioQueueRef audioQueue;
AudioQueueBufferRef buffers[kNumberBuffers];
AudioStreamBasicDescription format;
memset(&format, 0, sizeof(format));
format.mSampleRate = 44100;
format.mFormatID = kAudioFormatLinearPCM;
format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
format.mChannelsPerFrame = 1;
format.mBitsPerChannel = 16;
format.mBytesPerFrame = (format.mBitsPerChannel / 8) * format.mChannelsPerFrame;
format.mFramesPerPacket = 1;
format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket;
AudioQueueNewOutput(&format,
AQOutputCallback,
self,
CFRunLoopGetCurrent(),
kCFRunLoopCommonModes,
0,
&audioQueue);
// allocate and fill the buffers
for (int i = 0; i < kNumberBuffers; ++i)
{
AudioQueueAllocateBuffer(audioQueue, kBufferSize, &buffers[i]);
AQOutputCallback(self, audioQueue, buffers[i]);
}
AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, 1.0);
AudioQueueStart(audioQueue, NULL);
}
- (void)handleBufferCompleteForQueue:(AudioQueueRef)inAQ
buffer:(AudioQueueBufferRef)inBuffer
{
inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity;
int *buffer = (int *)inBuffer->mAudioData;
for (int i = 0; i < inBuffer->mAudioDataByteSize/sizeof(int); ++i)
{
buffer[i] = (int)rand(); // refill the buffer
}
AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
}
// END STATIC ADDITIONS
#end
Once I figured out how to actually refill the buffer (inBuffer->mAudioData with some type casting) everything else fell into place.

std::list problem for iPhone development

I found some problems for std::list when I'm doing some iPhone development under Xcode. Here is the code:
///////////// interface //////////////
class CObj
{
public:
int value;
};
typedef std::list<CObj*> ObjList;
#interface testAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
ObjList m_objs;
}
//////////// implementation /////////
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
for (int i = 0; i< 10; i++ )
{
CObj* obj = new CObj;
obj->value = i;
m_objs.push_back(obj);
}
NSLog(#"%d objects",m_objs.size() );
ObjList::iterator it = m_objs.begin();
while (it != m_objs.end())
{
CObj* obj = *it;
if ( obj->value == 3 )
it = m_objs.erase(it);
else
it++;
}
NSLog(#"%d objects",m_objs.size() );
}
The application simply crashes at m_objs.push_back. But if I change the std::list to std::vector, everything's fine. Any idea? Thanks
By default Objective-C does not call the constructor for c++ types on initialization.
If you set this flag in the build settings "Call C++ Default Ctors/Dtors in Objective-C", it will change the default behavior. Be aware that the flag only shows up if you have the target set to Device.