For iOS, you would need 4 files. One of the files would get reused with the Android version.
You could try something like this:
SimpleAudioRecordEngine.h (this would be the file shared between platforms):
#ifndef __SIMPLE_AUDIO_RECORD_ENGINE_H__
#define __SIMPLE_AUDIO_RECORD_ENGINE_H__
#include "Export.h"
namespace CocosDenshion
{
class EXPORT_DLL SimpleAudioRecordEngine
{
public:
static SimpleAudioRecordEngine *getInstance();
protected:
SimpleAudioRecordEngine();
virtual ~SimpleAudioRecordEngine();
public:
virtual bool checkMic();
virtual bool isRecording();
virtual void initRecord(const char *fileName);
virtual void startRecord();
virtual void stopRecord();
};
}
iOS specific files:
SimpleAudioRecordEngine.mm
#include "SimpleAudioRecordEngine.h"
#include "SimpleAudioRecordEngine_objc.h"
#include "cocos2d.h"
USING_NS_CC;
static bool static_checkMic()
{
return [[SimpleAudioRecordEngine sharedEngine] checkMic];
}
static bool static_isRecording()
{
return [[SimpleAudioRecordEngine sharedEngine] isRecording];
}
static void static_initRecord(const char *fileName)
{
[[SimpleAudioRecordEngine sharedEngine] initRecord:[NSString stringWithUTF8String:fileName]];
}
static void static_startRecord()
{
[[SimpleAudioRecordEngine sharedEngine] startRecord];
}
static void static_stopRecord()
{
[[SimpleAudioRecordEngine sharedEngine] stopRecord];
}
namespace CocosDenshion
{
static SimpleAudioRecordEngine *s_pEngine;
SimpleAudioRecordEngine::SimpleAudioRecordEngine()
{
}
SimpleAudioRecordEngine::~SimpleAudioRecordEngine()
{
}
SimpleAudioRecordEngine *SimpleAudioRecordEngine::getInstance()
{
if (!s_pEngine)
{
s_pEngine = new SimpleAudioRecordEngine();
}
return s_pEngine;
}
bool SimpleAudioRecordEngine::checkMic()
{
return static_checkMic();
}
bool SimpleAudioRecordEngine::isRecording()
{
return static_isRecording();
}
void SimpleAudioRecordEngine::initRecord(const char *fileName)
{
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);
static_initRecord(fullPath.c_str());
}
void SimpleAudioRecordEngine::startRecord()
{
static_startRecord();
}
void SimpleAudioRecordEngine::stopRecord()
{
static_stopRecord();
}
}
SimpleAudioRecordEngine_objc.h
#import <AVFoundation/AVFoundation.h>
#import <Foundation/Foundation.h>
@interface SimpleAudioRecordEngine : NSObject <AVAudioRecorderDelegate>
{
AVAudioRecorder *_recorder;
AVAudioSession *_audioSession;
NSString *_documentsPath;
}
@property (nonatomic, retain) AVAudioRecorder *recorder;
+ (SimpleAudioRecordEngine *)sharedEngine;
- (BOOL)checkMic;
- (BOOL)isRecording;
- (void)initRecord:(NSString *)fileName;
- (void)startRecord;
- (void)stopRecord;
- (NSString *)documentsPath;
@end
SimpleAudioRecordEngine_objc.m
#import "SimpleAudioRecordEngine_objc.h"
#import "audio/ios/SimpleAudioEngine_objc.h"
@implementation SimpleAudioRecordEngine
@synthesize recorder = _recorder;
static SimpleAudioRecordEngine *sharedEngine = nil;
#pragma mark -
#pragma mark Life Cycle Methods
+ (SimpleAudioRecordEngine *)sharedEngine
{
@synchronized(self)
{
if (!sharedEngine)
sharedEngine = [[SimpleAudioRecordEngine alloc] init];
}
return sharedEngine;
}
+ (id)alloc
{
@synchronized(self)
{
NSAssert(sharedEngine == nil, @"Attempted to allocate a second instance of a singleton");
return [super alloc];
}
return nil;
}
- (id)init
{
if ((self = [super init]))
{
NSError *error = nil;
_audioSession = [AVAudioSession sharedInstance];
[_audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
if (error)
{
NSLog(@"1: error: %@", [error localizedDescription]);
}
[_audioSession setActive:YES error:&error];
if (error)
{
NSLog(@"2: error: %@", [error localizedDescription]);
}
}
return self;
}
- (void)dealloc
{
[_recorder stop];
[_recorder release];
[_documentsPath release];
[super dealloc];
}
#pragma mark -
#pragma mark Recording Methods
- (BOOL)checkMic
{
if (_audioSession)
return _audioSession.inputIsAvailable;
return NO;
}
- (BOOL)isRecording
{
if (!_recorder)
return NO;
return _recorder.isRecording;
}
- (void)initRecord:(NSString *)fileName
{
if (_recorder)
{
[_recorder stop];
[_recorder release];
_recorder = nil;
}
NSURL *fileURL = [NSURL fileURLWithPath:[[self documentsPath] stringByAppendingPathComponent:fileName]];
NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
[NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
[NSNumber numberWithInt: 16], AVEncoderBitRateKey,
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
[NSNumber numberWithInt: AVAudioQualityMax], AVEncoderAudioQualityKey,
nil];
NSError *error = nil;
_recorder = [[AVAudioRecorder alloc] initWithURL:fileURL settings:settings error:nil];
_recorder.delegate = self;
if (error)
{
NSLog(@"3: error: %@", [error localizedDescription]);
}
}
- (void)startRecord
{
if (_recorder)
{
if ([_recorder record])
{
NSLog(@"Success recording!");
}
else
{
NSLog(@"Fail recording!");
}
}
}
- (void)stopRecord
{
[_recorder stop];
}
- (NSString *)documentsPath
{
if (!_documentsPath)
{
NSArray *searchPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
_documentsPath = [searchPath objectAtIndex:0];
[_documentsPath retain];
}
return _documentsPath;
}
#pragma mark -
#pragma mark Audio Recording Delegate Methods
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
}
@end
NOTE: this hasn’t been thoroughly tested, but seems to record audio successfully.
I haven’t looked into writing the Android side yet, and probably won’t get around to it for a while. But I think you should have enough to start with. I highly recommend looking at the existing platform specific class implementations, like SimpleAudioEngine, to see how to create your own.