Re: Synthesizing sound for the iPhone
Re: Synthesizing sound for the iPhone
- Subject: Re: Synthesizing sound for the iPhone
- From: Marc Vaillant <email@hidden>
- Date: Fri, 19 Dec 2008 10:11:29 -0500
- Mail-followup-to: Niklas Saers <email@hidden>, CoreAudio list <email@hidden>
Nik,
On Fri, Dec 19, 2008 at 09:37:25AM +0100, Niklas Saers wrote:
> Hi guys,
> I'm trying to get a sin tone at 415 Hz to play on the iPhone using
> AudioQueue. The source (20kb) is here: http://saers.dk/~niklas/sin.tgz
I haven't used AudioQueue and I don't have time to look at your code but
attached is an example of exactly what you want to do using the RemoteIO
AudioUnit, which should be more efficient than using AudioQueue anyway.
It's objc++ but the only thing that's c++ in it is the use of
std::vector to store the buffer data.
Good luck.
Marc
//
// AudioUnitTestAppDelegate.m
// AudioUnitTest
//
// Created by Marc Vaillant on 11/25/08.
// Copyright __MyCompanyName__ 2008. All rights reserved.
//
#import "AudioUnitTestAppDelegate.h"
#include <AudioUnit/AudioUnit.h>
//#include "MachTimer.hpp"
#include <vector>
#include <iostream>
using namespace std;
#define kOutputBus 0
#define kInputBus 1
#define SAMPLE_RATE 44100
vector<int> _pcm;
int _index;
@implementation AudioUnitTestAppDelegate
@synthesize window;
void generateTone(
vector<int>& pcm,
int freq,
double lengthMS,
int sampleRate,
double riseTimeMS,
double gain)
{
int numSamples = ((double) sampleRate) * lengthMS / 1000.;
int riseTimeSamples = ((double) sampleRate) * riseTimeMS / 1000.;
if(gain > 1.)
gain = 1.;
if(gain < 0.)
gain = 0.;
pcm.resize(numSamples);
for(int i = 0; i < numSamples; ++i)
{
double value = sin(2. * M_PI * freq * i / sampleRate);
if(i < riseTimeSamples)
value *= sin(i * M_PI / (2.0 * riseTimeSamples));
if(i > numSamples - riseTimeSamples - 1)
value *= sin(2. * M_PI * (i - (numSamples - riseTimeSamples) + riseTimeSamples)/ (4. * riseTimeSamples));
pcm[i] = (int) (value * 32500.0 * gain);
pcm[i] += (pcm[i]<<16);
}
}
static OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
cout<<"index = "<<_index<<endl;
cout<<"numBuffers = "<<ioData->mNumberBuffers<<endl;
int totalNumberOfSamples = _pcm.size();
for(UInt32 i = 0; i < ioData->mNumberBuffers; ++i)
{
int samplesLeft = totalNumberOfSamples - _index;
int numSamples = ioData->mBuffers[i].mDataByteSize / 4;
if(samplesLeft > 0)
{
if(samplesLeft < numSamples)
{
memcpy(ioData->mBuffers[i].mData, &_pcm[_index], samplesLeft * 4);
_index += samplesLeft;
memset((char*) ioData->mBuffers[i].mData + samplesLeft * 4, 0, (numSamples - samplesLeft) * 4) ;
}
else
{
memcpy(ioData->mBuffers[i].mData, &_pcm[_index], numSamples * 4) ;
_index += numSamples;
}
}
else
memset(ioData->mBuffers[i].mData, 0, ioData->mBuffers[i].mDataByteSize);
}
return noErr;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
//generate pcm tone freq = 800, duration = 1s, rise/fall time = 5ms
generateTone(_pcm, 800, 1000, SAMPLE_RATE, 5, 0.8);
_index = 0;
OSStatus status;
AudioComponentInstance audioUnit;
// Describe audio component
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
// Get component
AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);
// Get audio units
status = AudioComponentInstanceNew(inputComponent, &audioUnit);
//checkStatus(status);
UInt32 flag = 1;
// Enable IO for playback
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
kOutputBus,
&flag,
sizeof(flag));
//checkStatus(status);
// Describe format
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = SAMPLE_RATE;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 2;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 4;
audioFormat.mBytesPerFrame = 4;
// Apply format
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
kOutputBus,
&audioFormat,
sizeof(audioFormat));
// checkStatus(status);
// Set output callback
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = playbackCallback;
callbackStruct.inputProcRefCon = self;
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
kOutputBus,
&callbackStruct,
sizeof(callbackStruct));
// Initialize
status = AudioUnitInitialize(audioUnit);
// Start playing
status = AudioOutputUnitStart(audioUnit);
[window makeKeyAndVisible];
}
- (void)dealloc {
[window release];
[super dealloc];
}
@end
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden