|
Carlos Lopez |
a09598 |
//
|
|
Carlos Lopez |
a09598 |
// QuartzAudio.m
|
|
Carlos Lopez |
a09598 |
//
|
|
Carlos Lopez |
a09598 |
// X Window bell support using CoreAudio or AppKit.
|
|
Carlos Lopez |
a09598 |
// Greg Parker gparker@cs.stanford.edu 19 Feb 2001
|
|
Carlos Lopez |
a09598 |
//
|
|
Carlos Lopez |
a09598 |
// Info about sine wave sound playback:
|
|
Carlos Lopez |
a09598 |
// CoreAudio code derived from macosx-dev posting by Tim Wood
|
|
Carlos Lopez |
a09598 |
// http://www.omnigroup.com/mailman/archive/macosx-dev/2000-May/002004.html
|
|
Carlos Lopez |
a09598 |
// Smoothing transitions between sounds
|
|
Carlos Lopez |
a09598 |
// http://www.wam.umd.edu/~mphoenix/dss/dss.html
|
|
Carlos Lopez |
a09598 |
//
|
|
Carlos Lopez |
a09598 |
/*
|
|
Carlos Lopez |
a09598 |
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
|
|
Carlos Lopez |
a09598 |
*
|
|
Carlos Lopez |
a09598 |
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
Carlos Lopez |
a09598 |
* copy of this software and associated documentation files (the "Software"),
|
|
Carlos Lopez |
a09598 |
* to deal in the Software without restriction, including without limitation
|
|
Carlos Lopez |
a09598 |
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
Carlos Lopez |
a09598 |
* and/or sell copies of the Software, and to permit persons to whom the
|
|
Carlos Lopez |
a09598 |
* Software is furnished to do so, subject to the following conditions:
|
|
Carlos Lopez |
a09598 |
*
|
|
Carlos Lopez |
a09598 |
* The above copyright notice and this permission notice shall be included in
|
|
Carlos Lopez |
a09598 |
* all copies or substantial portions of the Software.
|
|
Carlos Lopez |
a09598 |
*
|
|
Carlos Lopez |
a09598 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
Carlos Lopez |
a09598 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
Carlos Lopez |
a09598 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
Carlos Lopez |
a09598 |
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
Carlos Lopez |
a09598 |
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
Carlos Lopez |
a09598 |
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
Carlos Lopez |
a09598 |
* DEALINGS IN THE SOFTWARE.
|
|
Carlos Lopez |
a09598 |
*
|
|
Carlos Lopez |
a09598 |
* Except as contained in this notice, the name(s) of the above copyright
|
|
Carlos Lopez |
a09598 |
* holders shall not be used in advertising or otherwise to promote the sale,
|
|
Carlos Lopez |
a09598 |
* use or other dealings in this Software without prior written authorization.
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzAudio.c,v 1.1 2002/03/28 02:21:18 torrey Exp $ */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include "quartz.h"
|
|
Carlos Lopez |
a09598 |
#include "quartz-audio.h"
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include <coreaudio coreaudio.h=""></coreaudio>
|
|
Carlos Lopez |
a09598 |
#include <pthread.h></pthread.h>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include "inputstr.h"
|
|
Carlos Lopez |
a09598 |
#include "extensions/XI.h"
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void NSBeep();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
typedef struct QuartzAudioRec {
|
|
Carlos Lopez |
a09598 |
double frequency;
|
|
Carlos Lopez |
a09598 |
double amplitude;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
UInt32 curFrame;
|
|
Carlos Lopez |
a09598 |
UInt32 remainingFrames;
|
|
Carlos Lopez |
a09598 |
UInt32 totalFrames;
|
|
Carlos Lopez |
a09598 |
UInt32 bytesPerFrame;
|
|
Carlos Lopez |
a09598 |
double sampleRate;
|
|
Carlos Lopez |
a09598 |
UInt32 fadeLength;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
UInt32 bufferByteCount;
|
|
Carlos Lopez |
a09598 |
Boolean playing;
|
|
Carlos Lopez |
a09598 |
pthread_mutex_t lock;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// used to fade out interrupted sound and avoid 'pop'
|
|
Carlos Lopez |
a09598 |
double prevFrequency;
|
|
Carlos Lopez |
a09598 |
double prevAmplitude;
|
|
Carlos Lopez |
a09598 |
UInt32 prevFrame;
|
|
Carlos Lopez |
a09598 |
} QuartzAudioRec;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static AudioDeviceID quartzAudioDevice = kAudioDeviceUnknown;
|
|
Carlos Lopez |
a09598 |
static QuartzAudioRec data;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/*
|
|
Carlos Lopez |
a09598 |
* QuartzAudioEnvelope
|
|
Carlos Lopez |
a09598 |
* Fade sound in and out to avoid pop.
|
|
Carlos Lopez |
a09598 |
* Sounds with shorter duration will never reach full amplitude. Deal.
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
static double QuartzAudioEnvelope(
|
|
Carlos Lopez |
a09598 |
UInt32 curFrame,
|
|
Carlos Lopez |
a09598 |
UInt32 totalFrames,
|
|
Carlos Lopez |
a09598 |
UInt32 fadeLength )
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
double fadeFrames = min(fadeLength, totalFrames / 2);
|
|
Carlos Lopez |
a09598 |
if (fadeFrames < 1) return 0;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (curFrame < fadeFrames) {
|
|
Carlos Lopez |
a09598 |
return curFrame / fadeFrames;
|
|
Carlos Lopez |
a09598 |
} else if (curFrame > totalFrames - fadeFrames) {
|
|
Carlos Lopez |
a09598 |
return (totalFrames-curFrame) / fadeFrames;
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
return 1.0;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/*
|
|
Carlos Lopez |
a09598 |
* QuartzFillBuffer
|
|
Carlos Lopez |
a09598 |
* Fill this buffer with data and update the data position.
|
|
Carlos Lopez |
a09598 |
* FIXME: this is ugly
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
static void QuartzFillBuffer(
|
|
Carlos Lopez |
a09598 |
AudioBuffer *audiobuffer,
|
|
Carlos Lopez |
a09598 |
QuartzAudioRec *data )
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
float *buffer, *b;
|
|
Carlos Lopez |
a09598 |
unsigned int frame, frameCount;
|
|
Carlos Lopez |
a09598 |
unsigned int bufferFrameCount;
|
|
Carlos Lopez |
a09598 |
float multiplier, v;
|
|
Carlos Lopez |
a09598 |
int i;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
buffer = (float *)audiobuffer->mData;
|
|
Carlos Lopez |
a09598 |
bufferFrameCount = audiobuffer->mDataByteSize / data->bytesPerFrame;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
frameCount = min(bufferFrameCount, data->remainingFrames);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Fade out previous sine wave, if any.
|
|
Carlos Lopez |
a09598 |
b = buffer;
|
|
Carlos Lopez |
a09598 |
if (data->prevFrame) {
|
|
Carlos Lopez |
a09598 |
multiplier = 2*M_PI*(data->prevFrequency/data->sampleRate);
|
|
Carlos Lopez |
a09598 |
for (frame = 0; frame < data->fadeLength; frame++) {
|
|
Carlos Lopez |
a09598 |
v = data->prevAmplitude *
|
|
Carlos Lopez |
a09598 |
QuartzAudioEnvelope(frame+data->fadeLength,
|
|
Carlos Lopez |
a09598 |
2*data->fadeLength,
|
|
Carlos Lopez |
a09598 |
data->fadeLength) *
|
|
Carlos Lopez |
a09598 |
sin(multiplier * (data->prevFrame+frame));
|
|
Carlos Lopez |
a09598 |
for (i = 0; i < audiobuffer->mNumberChannels; i++) {
|
|
Carlos Lopez |
a09598 |
*b++ = v;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
// no more prev fade
|
|
Carlos Lopez |
a09598 |
data->prevFrame = 0;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// adjust for space eaten by prev fade
|
|
Carlos Lopez |
a09598 |
buffer += audiobuffer->mNumberChannels*frame;
|
|
Carlos Lopez |
a09598 |
bufferFrameCount -= frame;
|
|
Carlos Lopez |
a09598 |
frameCount = min(bufferFrameCount, data->remainingFrames);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Write a sine wave with the specified frequency and amplitude
|
|
Carlos Lopez |
a09598 |
multiplier = 2*M_PI*(data->frequency/data->sampleRate);
|
|
Carlos Lopez |
a09598 |
for (frame = 0; frame < frameCount; frame++) {
|
|
Carlos Lopez |
a09598 |
v = data->amplitude *
|
|
Carlos Lopez |
a09598 |
QuartzAudioEnvelope(data->curFrame+frame, data->totalFrames,
|
|
Carlos Lopez |
a09598 |
data->fadeLength) *
|
|
Carlos Lopez |
a09598 |
sin(multiplier * (data->curFrame+frame));
|
|
Carlos Lopez |
a09598 |
for (i = 0; i < audiobuffer->mNumberChannels; i++) {
|
|
Carlos Lopez |
a09598 |
*b++ = v;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Zero out the rest of the buffer, if any
|
|
Carlos Lopez |
a09598 |
memset(b, 0, sizeof(float) * audiobuffer->mNumberChannels *
|
|
Carlos Lopez |
a09598 |
(bufferFrameCount-frame));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
data->curFrame += frameCount;
|
|
Carlos Lopez |
a09598 |
data->remainingFrames -= frameCount;
|
|
Carlos Lopez |
a09598 |
if (data->remainingFrames == 0) {
|
|
Carlos Lopez |
a09598 |
data->playing = FALSE;
|
|
Carlos Lopez |
a09598 |
data->curFrame = 0;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/*
|
|
Carlos Lopez |
a09598 |
* QuartzAudioIOProc
|
|
Carlos Lopez |
a09598 |
* Callback function for audio playback.
|
|
Carlos Lopez |
a09598 |
* FIXME: use inOutputTime to correct for skipping
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
static OSStatus
|
|
Carlos Lopez |
a09598 |
QuartzAudioIOProc(
|
|
Carlos Lopez |
a09598 |
AudioDeviceID inDevice,
|
|
Carlos Lopez |
a09598 |
const AudioTimeStamp *inNow,
|
|
Carlos Lopez |
a09598 |
const AudioBufferList *inInputData,
|
|
Carlos Lopez |
a09598 |
const AudioTimeStamp *inInputTime,
|
|
Carlos Lopez |
a09598 |
AudioBufferList *outOutputData,
|
|
Carlos Lopez |
a09598 |
const AudioTimeStamp *inOutputTime,
|
|
Carlos Lopez |
a09598 |
void *inClientData )
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
QuartzAudioRec *data = (QuartzAudioRec *)inClientData;
|
|
Carlos Lopez |
a09598 |
int i;
|
|
Carlos Lopez |
a09598 |
Boolean wasPlaying;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pthread_mutex_lock(&data->lock);
|
|
Carlos Lopez |
a09598 |
wasPlaying = data->playing;
|
|
Carlos Lopez |
a09598 |
for (i = 0; i < outOutputData->mNumberBuffers; i++) {
|
|
Carlos Lopez |
a09598 |
if (data->playing) {
|
|
Carlos Lopez |
a09598 |
QuartzFillBuffer(outOutputData->mBuffers+i, data);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else {
|
|
Carlos Lopez |
a09598 |
memset(outOutputData->mBuffers[i].mData, 0,
|
|
Carlos Lopez |
a09598 |
outOutputData->mBuffers[i].mDataByteSize);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
if (wasPlaying && !data->playing) {
|
|
Carlos Lopez |
a09598 |
OSStatus err;
|
|
Carlos Lopez |
a09598 |
err = AudioDeviceStop(inDevice, QuartzAudioIOProc);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
pthread_mutex_unlock(&data->lock);
|
|
Carlos Lopez |
a09598 |
return 0;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/*
|
|
Carlos Lopez |
a09598 |
* QuartzCoreAudioBell
|
|
Carlos Lopez |
a09598 |
* Play a tone using the CoreAudio API
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
static void QuartzCoreAudioBell(
|
|
Carlos Lopez |
a09598 |
int volume, // volume is % of max
|
|
Carlos Lopez |
a09598 |
int pitch, // pitch is Hz
|
|
Carlos Lopez |
a09598 |
int duration ) // duration is milliseconds
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (quartzAudioDevice == kAudioDeviceUnknown) return;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pthread_mutex_lock(&data.lock);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// fade previous sound, if any
|
|
Carlos Lopez |
a09598 |
data.prevFrequency = data.frequency;
|
|
Carlos Lopez |
a09598 |
data.prevAmplitude = data.amplitude;
|
|
Carlos Lopez |
a09598 |
data.prevFrame = data.curFrame;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// set new sound
|
|
Carlos Lopez |
a09598 |
data.frequency = pitch;
|
|
Carlos Lopez |
a09598 |
data.amplitude = volume / 100.0;
|
|
Carlos Lopez |
a09598 |
data.curFrame = 0;
|
|
Carlos Lopez |
a09598 |
data.totalFrames = (int)(data.sampleRate * duration / 1000.0);
|
|
Carlos Lopez |
a09598 |
data.remainingFrames = data.totalFrames;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (! data.playing) {
|
|
Carlos Lopez |
a09598 |
OSStatus status;
|
|
Carlos Lopez |
a09598 |
status = AudioDeviceStart(quartzAudioDevice, QuartzAudioIOProc);
|
|
Carlos Lopez |
a09598 |
if (status) {
|
|
Carlos Lopez |
a09598 |
ErrorF("QuartzAudioBell: AudioDeviceStart returned %d\n", status);
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
data.playing = TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
pthread_mutex_unlock(&data.lock);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/*
|
|
Carlos Lopez |
a09598 |
* QuartzBell
|
|
Carlos Lopez |
a09598 |
* Ring the bell
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
void QuartzBell(
|
|
Carlos Lopez |
a09598 |
int volume, // volume in percent of max
|
|
Carlos Lopez |
a09598 |
DeviceIntPtr pDevice,
|
|
Carlos Lopez |
a09598 |
pointer ctrl,
|
|
Carlos Lopez |
a09598 |
int class )
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int pitch; // pitch in Hz
|
|
Carlos Lopez |
a09598 |
int duration; // duration in milliseconds
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (class == BellFeedbackClass) {
|
|
Carlos Lopez |
a09598 |
pitch = ((BellCtrl*)ctrl)->pitch;
|
|
Carlos Lopez |
a09598 |
duration = ((BellCtrl*)ctrl)->duration;
|
|
Carlos Lopez |
a09598 |
} else if (class == KbdFeedbackClass) {
|
|
Carlos Lopez |
a09598 |
pitch = ((KeybdCtrl*)ctrl)->bell_pitch;
|
|
Carlos Lopez |
a09598 |
duration = ((KeybdCtrl*)ctrl)->bell_duration;
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
ErrorF("QuartzBell: bad bell class %d\n", class);
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (quartzUseSysBeep) {
|
|
Carlos Lopez |
a09598 |
if (volume)
|
|
Carlos Lopez |
a09598 |
NSBeep();
|
|
Carlos Lopez |
a09598 |
} else {
|
|
Carlos Lopez |
a09598 |
QuartzCoreAudioBell(volume, pitch, duration);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/*
|
|
Carlos Lopez |
a09598 |
* QuartzAudioInit
|
|
Carlos Lopez |
a09598 |
* Prepare to play the bell with the CoreAudio API
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
void QuartzAudioInit(void)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
UInt32 propertySize;
|
|
Carlos Lopez |
a09598 |
OSStatus status;
|
|
Carlos Lopez |
a09598 |
AudioDeviceID outputDevice;
|
|
Carlos Lopez |
a09598 |
AudioStreamBasicDescription outputStreamDescription;
|
|
Carlos Lopez |
a09598 |
double sampleRate;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Get the default output device
|
|
Carlos Lopez |
a09598 |
propertySize = sizeof(outputDevice);
|
|
Carlos Lopez |
a09598 |
status = AudioHardwareGetProperty(
|
|
Carlos Lopez |
a09598 |
kAudioHardwarePropertyDefaultOutputDevice,
|
|
Carlos Lopez |
a09598 |
&propertySize, &outputDevice);
|
|
Carlos Lopez |
a09598 |
if (status) {
|
|
Carlos Lopez |
a09598 |
ErrorF("QuartzAudioInit: AudioHardwareGetProperty returned %d\n",
|
|
Carlos Lopez |
a09598 |
status);
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
if (outputDevice == kAudioDeviceUnknown) {
|
|
Carlos Lopez |
a09598 |
ErrorF("QuartzAudioInit: No audio output devices available.\n");
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Get the basic device description
|
|
Carlos Lopez |
a09598 |
propertySize = sizeof(outputStreamDescription);
|
|
Carlos Lopez |
a09598 |
status = AudioDeviceGetProperty(outputDevice, 0, FALSE,
|
|
Carlos Lopez |
a09598 |
kAudioDevicePropertyStreamFormat,
|
|
Carlos Lopez |
a09598 |
&propertySize, &outputStreamDescription);
|
|
Carlos Lopez |
a09598 |
if (status) {
|
|
Carlos Lopez |
a09598 |
ErrorF("QuartzAudioInit: GetProperty(stream format) returned %d\n",
|
|
Carlos Lopez |
a09598 |
status);
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
sampleRate = outputStreamDescription.mSampleRate;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Fill in the playback data
|
|
Carlos Lopez |
a09598 |
data.frequency = 0;
|
|
Carlos Lopez |
a09598 |
data.amplitude = 0;
|
|
Carlos Lopez |
a09598 |
data.curFrame = 0;
|
|
Carlos Lopez |
a09598 |
data.remainingFrames = 0;
|
|
Carlos Lopez |
a09598 |
data.bytesPerFrame = outputStreamDescription.mBytesPerFrame;
|
|
Carlos Lopez |
a09598 |
data.sampleRate = sampleRate;
|
|
Carlos Lopez |
a09598 |
// data.bufferByteCount = bufferByteCount;
|
|
Carlos Lopez |
a09598 |
data.playing = FALSE;
|
|
Carlos Lopez |
a09598 |
data.prevAmplitude = 0;
|
|
Carlos Lopez |
a09598 |
data.prevFrame = 0;
|
|
Carlos Lopez |
a09598 |
data.prevFrequency = 0;
|
|
Carlos Lopez |
a09598 |
data.fadeLength = data.sampleRate / 200;
|
|
Carlos Lopez |
a09598 |
pthread_mutex_init(&data.lock, NULL); // fixme error check
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// fixme assert fadeLength
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Prepare for playback
|
|
Carlos Lopez |
a09598 |
status = AudioDeviceAddIOProc(outputDevice, QuartzAudioIOProc, &data);
|
|
Carlos Lopez |
a09598 |
if (status) {
|
|
Carlos Lopez |
a09598 |
ErrorF("QuartzAudioInit: AddIOProc returned %d\n", status);
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// success!
|
|
Carlos Lopez |
a09598 |
quartzAudioDevice = outputDevice;
|
|
Carlos Lopez |
a09598 |
}
|