[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Traverso-commit] traverso/src/engine AudioDevice.h CoreAudioDriv...
From: |
Remon Sijrier |
Subject: |
[Traverso-commit] traverso/src/engine AudioDevice.h CoreAudioDriv... |
Date: |
Mon, 24 Nov 2008 11:17:29 +0000 |
CVSROOT: /sources/traverso
Module name: traverso
Changes by: Remon Sijrier <r_sijrier> 08/11/24 11:17:29
Modified files:
src/engine : AudioDevice.h CoreAudioDriver.cpp
CoreAudioDriver.h
Log message:
* Some functions ported, please compile test!
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/AudioDevice.h?cvsroot=traverso&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/CoreAudioDriver.cpp?cvsroot=traverso&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/CoreAudioDriver.h?cvsroot=traverso&r1=1.2&r2=1.3
Patches:
Index: AudioDevice.h
===================================================================
RCS file: /sources/traverso/traverso/src/engine/AudioDevice.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- AudioDevice.h 18 Feb 2008 08:17:31 -0000 1.29
+++ AudioDevice.h 24 Nov 2008 11:17:28 -0000 1.30
@@ -45,6 +45,11 @@
class JackDriver;
#endif
+#if defined (COREAUDIO_SUPPORT)
+class CoreAudioDriver;
+#endif
+
+
class AudioDevice : public QObject
{
Q_OBJECT
@@ -142,7 +147,9 @@
friend class Driver;
friend class PulseAudioDriver;
friend class AudioDeviceThread;
-
+#if defined (COREAUDIO_SUPPORT)
+ friend class CoreAudioDriver;
+#endif
Driver* driver;
AudioDeviceThread* audioThread;
Index: CoreAudioDriver.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/engine/CoreAudioDriver.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- CoreAudioDriver.cpp 21 Nov 2008 13:40:14 -0000 1.2
+++ CoreAudioDriver.cpp 24 Nov 2008 11:17:28 -0000 1.3
@@ -66,6 +66,9 @@
#include "Debugger.h"
+//#define PRINTDEBUG 1
+
+
CoreAudioDriver::CoreAudioDriver(AudioDevice * dev, int rate, nframes_t
bufferSize)
: Driver(dev, rate, bufferSize)
{
@@ -77,6 +80,380 @@
PENTERDES;
}
+
+
+void JCALog(char *fmt, ...)
+{
+#ifdef PRINTDEBUG
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "JCA: ");
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+#endif
+}
+
+void printError(OSStatus err)
+{
+#ifdef DEBUG
+ switch (err) {
+ case kAudioHardwareNoError:
+ JCALog("error code : kAudioHardwareNoError\n");
+ break;
+ case kAudioHardwareNotRunningError:
+ JCALog("error code : kAudioHardwareNotRunningError\n");
+ break;
+ case kAudioHardwareUnspecifiedError:
+ JCALog("error code : kAudioHardwareUnspecifiedError\n");
+ break;
+ case kAudioHardwareUnknownPropertyError:
+ JCALog("error code : kAudioHardwareUnknownPropertyError\n");
+ break;
+ case kAudioHardwareBadPropertySizeError:
+ JCALog("error code : kAudioHardwareBadPropertySizeError\n");
+ break;
+ case kAudioHardwareIllegalOperationError:
+ JCALog("error code : kAudioHardwareIllegalOperationError\n");
+ break;
+ case kAudioHardwareBadDeviceError:
+ JCALog("error code : kAudioHardwareBadDeviceError\n");
+ break;
+ case kAudioHardwareBadStreamError:
+ JCALog("error code : kAudioHardwareBadStreamError\n");
+ break;
+ case kAudioDeviceUnsupportedFormatError:
+ JCALog("error code : kAudioDeviceUnsupportedFormatError\n");
+ break;
+ case kAudioDevicePermissionsError:
+ JCALog("error code : kAudioDevicePermissionsError\n");
+ break;
+ default:
+ JCALog("error code : unknown %ld\n", err);
+ break;
+ }
+#endif
+}
+
+OSStatus get_device_name_from_id(AudioDeviceID id, char name[256])
+{
+ UInt32 size = sizeof(char) * 256;
+ OSStatus res = AudioDeviceGetProperty(id, 0, false,
+ kAudioDevicePropertyDeviceName,
+ &size,
+ &name[0]);
+ return res;
+}
+
+OSStatus get_device_id_from_uid(char* UID, AudioDeviceID* id)
+{
+ UInt32 size = sizeof(AudioValueTranslation);
+ CFStringRef inIUD = CFStringCreateWithCString(NULL, UID,
CFStringGetSystemEncoding());
+ AudioValueTranslation value = { &inIUD, sizeof(CFStringRef), id,
sizeof(AudioDeviceID) };
+ if (inIUD == NULL) {
+ return kAudioHardwareUnspecifiedError;
+ } else {
+ OSStatus res =
AudioHardwareGetProperty(kAudioHardwarePropertyDeviceForUID, &size, &value);
+ CFRelease(inIUD);
+ JCALog("get_device_id_from_uid %s %ld \n", UID, *id);
+ return (*id == kAudioDeviceUnknown) ?
kAudioHardwareBadDeviceError : res;
+ }
+}
+
+OSStatus get_default_device(AudioDeviceID * id)
+{
+ OSStatus res;
+ UInt32 theSize = sizeof(UInt32);
+ AudioDeviceID inDefault;
+ AudioDeviceID outDefault;
+
+ if ((res =
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
+ &theSize, &inDefault)) != noErr)
+ return res;
+
+ if ((res =
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+ &theSize, &outDefault)) != noErr)
+ return res;
+
+ JCALog("get_default_device: input %ld output %ld\n", inDefault,
outDefault);
+
+ // Get the device only if default input and ouput are the same
+ if (inDefault == outDefault) {
+ *id = inDefault;
+ return noErr;
+ } else {
+ PERROR("CoreAudioDriver:: Default input and output devices are
not the same !!");
+ return kAudioHardwareBadDeviceError;
+ }
+}
+
+OSStatus get_default_input_device(AudioDeviceID* id)
+{
+ OSStatus res;
+ UInt32 theSize = sizeof(UInt32);
+ AudioDeviceID inDefault;
+
+ if ((res =
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
+ &theSize, &inDefault)) != noErr)
+ return res;
+
+ JCALog("get_default_input_device: input = %ld \n", inDefault);
+ *id = inDefault;
+ return noErr;
+}
+
+OSStatus get_default_output_device(AudioDeviceID* id)
+{
+ OSStatus res;
+ UInt32 theSize = sizeof(UInt32);
+ AudioDeviceID outDefault;
+
+ if ((res =
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+ &theSize, &outDefault)) !=
noErr)
+ return res;
+
+ JCALog("get_default_output_device: output = %ld\n", outDefault);
+ *id = outDefault;
+ return noErr;
+}
+
+OSStatus get_total_channels(AudioDeviceID device, int* channelCount, bool
isInput)
+{
+ OSStatus err = noErr;
+ UInt32 outSize;
+ Boolean outWritable;
+ AudioBufferList* bufferList = 0;
+ AudioStreamID* streamList = 0;
+ int i, numStream;
+
+ err = AudioDeviceGetPropertyInfo(device, 0, isInput,
kAudioDevicePropertyStreams, &outSize, &outWritable);
+ if (err == noErr) {
+ streamList = (AudioStreamID*)malloc(outSize);
+ numStream = outSize/sizeof(AudioStreamID);
+ JCALog("get_total_channels device stream number = %ld numStream
= %ld\n", device, numStream);
+ err = AudioDeviceGetProperty(device, 0, isInput,
kAudioDevicePropertyStreams, &outSize, streamList);
+ if (err == noErr) {
+ AudioStreamBasicDescription streamDesc;
+ outSize = sizeof(AudioStreamBasicDescription);
+ for (i = 0; i < numStream; i++) {
+ err = AudioStreamGetProperty(streamList[i], 0,
kAudioDevicePropertyStreamFormat, &outSize, &streamDesc);
+ JCALog("get_total_channels streamDesc
mFormatFlags = %ld mChannelsPerFrame = %ld\n", streamDesc.mFormatFlags,
streamDesc.mChannelsPerFrame);
+ }
+ }
+ }
+
+ *channelCount = 0;
+ err = AudioDeviceGetPropertyInfo(device, 0, isInput,
kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable);
+ if (err == noErr) {
+ bufferList = (AudioBufferList*)malloc(outSize);
+ err = AudioDeviceGetProperty(device, 0, isInput,
kAudioDevicePropertyStreamConfiguration, &outSize, bufferList);
+ if (err == noErr) {
+ for (i = 0; i < bufferList->mNumberBuffers; i++)
+ *channelCount +=
bufferList->mBuffers[i].mNumberChannels;
+ }
+ }
+
+ if (streamList)
+ free(streamList);
+ if (bufferList)
+ free(bufferList);
+
+ return err;
+}
+
+OSStatus display_device_names()
+{
+ UInt32 size;
+ Boolean isWritable;
+ int i, deviceNum;
+ OSStatus err;
+ CFStringRef UIname;
+
+ err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
&size, &isWritable);
+ if (err != noErr)
+ return err;
+
+ deviceNum = size/sizeof(AudioDeviceID);
+ AudioDeviceID devices[deviceNum];
+
+ err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size,
devices);
+ if (err != noErr)
+ return err;
+
+ for (i = 0; i < deviceNum; i++) {
+ char device_name[256];
+ char internal_name[256];
+
+ size = sizeof(CFStringRef);
+ UIname = NULL;
+ err = AudioDeviceGetProperty(devices[i], 0, false,
kAudioDevicePropertyDeviceUID, &size, &UIname);
+ if (err == noErr) {
+ CFStringGetCString(UIname, internal_name, 256,
CFStringGetSystemEncoding());
+ } else {
+ goto error;
+ }
+
+ size = 256;
+ err = AudioDeviceGetProperty(devices[i], 0, false,
kAudioDevicePropertyDeviceName, &size, device_name);
+ if (err != noErr)
+ return err;
+ printf("ICI\n");
+ printf("Device name = \'%s\', internal_name = \'%s\' (to be
used as -d parameter)\n", device_name, internal_name);
+ }
+
+ return noErr;
+
+error:
+ if (UIname != NULL)
+ CFRelease(UIname);
+ return err;
+}
+
+static OSStatus render(void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList *ioData)
+{
+ int res, i;
+ JSList *node;
+
+ CoreAudioDriver* ca_driver = (CoreAudioDriver*)inRefCon;
+ AudioUnitRender(ca_driver->au_hal, ioActionFlags, inTimeStamp, 1,
inNumberFrames, ca_driver->input_list);
+
+ if (ca_driver->xrun_detected > 0) { /* XRun was detected */
+ trav_time_t current_time = get_microseconds ();
+ ca_driver->device->delay(current_time -
(ca_driver->last_wait_ust + ca_driver->period_usecs));
+ ca_driver->last_wait_ust = current_time;
+ ca_driver->xrun_detected = 0;
+ return 0;
+ } else {
+ ca_driver->last_wait_ust = get_microseconds();
+ ca_driver->device->transport_cycle_start(get_microseconds());
+ res = ca_driver->device->run_cycle(inNumberFrames, 0);
+ }
+
+ if (ca_driver->null_cycle_occured) {
+ ca_driver->null_cycle_occured = 0;
+ for (i = 0; i < ca_driver->playback_nchannels; i++) {
+ memset((float*)ioData->mBuffers[i].mData, 0,
sizeof(float) * inNumberFrames);
+ }
+ } else {
+ // TODO find out if ioData->mBuffers[i] correspond with the
playbackChannels indices
+ for (int i=0; i<playbackChannels.size(); ++i) {
+ AudioChannel* channel = playbackChannels.at(i);
+ if (!channel->has_data()) {
+ continue;
+ }
+ buf = channel->get_data();
+
+ memcpy((float*)ioData->mBuffers[i].mData, buf,
sizeof(float) * inNumberFrames);
+
+ // Not sure if this is needed? I think so though
+ channel->silence_buffer(inNumberFrames);
+ }
+ }
+
+ return res;
+}
+
+static OSStatus render_input( void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList *ioData)
+{
+ CoreAudioDriver* ca_driver = (CoreAudioDriver*)inRefCon;
+ AudioUnitRender(ca_driver->au_hal, ioActionFlags, inTimeStamp, 1,
inNumberFrames, ca_driver->input_list);
+ if (ca_driver->xrun_detected > 0) { /* XRun was detected */
+ trav_time_t current_time = get_microseconds();
+ ca_driver->device->delay(current_time -
(ca_driver->last_wait_ust + ca_driver->period_usecs));
+ ca_driver->last_wait_ust = current_time;
+ ca_driver->xrun_detected = 0;
+ return 0;
+ } else {
+ ca_driver->last_wait_ust = get_microseconds();
+ ca_driver->device->transport_cycle_start(get_microseconds());
+ return ca_driver->device->run_cycle(inNumberFrames, 0);
+ }
+}
+
+
+static OSStatus sr_notification(AudioDeviceID inDevice,
+ UInt32 inChannel,
+ Boolean isInput,
+ AudioDevicePropertyID inPropertyID,
+ void* inClientData)
+{
+ CoreAudioDriver* driver = (CoreAudioDriver*)inClientData;
+
+ switch (inPropertyID) {
+
+ case kAudioDevicePropertyNominalSampleRate: {
+ JCALog("JackCoreAudioDriver::SRNotificationCallback
kAudioDevicePropertyNominalSampleRate \n");
+ driver->state = 1;
+ break;
+ }
+ }
+
+ return noErr;
+}
+
+static OSStatus notification(AudioDeviceID inDevice,
+ UInt32 inChannel,
+ Boolean isInput,
+ AudioDevicePropertyID inPropertyID,
+ void* inClientData)
+{
+ CoreAudioDriver* driver = (CoreAudioDriver*)inClientData;
+ switch (inPropertyID) {
+
+ case kAudioDeviceProcessorOverload:
+ driver->xrun_detected = 1;
+ break;
+
+ case kAudioDevicePropertyNominalSampleRate: {
+ UInt32 outSize = sizeof(Float64);
+ Float64 sampleRate;
+ AudioStreamBasicDescription srcFormat, dstFormat;
+ OSStatus err =
AudioDeviceGetProperty(driver->device_id, 0, kAudioDeviceSectionGlobal,
kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
+ if (err != noErr) {
+ PERROR("Cannot get current sample rate");
+ return kAudioHardwareUnsupportedOperationError;
+ }
+ JCALog("JackCoreAudioDriver::NotificationCallback
kAudioDevicePropertyNominalSampleRate %ld\n", (long)sampleRate);
+ outSize = sizeof(AudioStreamBasicDescription);
+
+ // Update SR for input
+ err = AudioUnitGetProperty(driver->au_hal,
kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat,
&outSize);
+ if (err != noErr) {
+ PERROR("Error calling AudioUnitSetProperty -
kAudioUnitProperty_StreamFormat kAudioUnitScope_Input");
+ }
+ srcFormat.mSampleRate = sampleRate;
+ err = AudioUnitSetProperty(driver->au_hal,
kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, outSize);
+ if (err != noErr) {
+ PERROR("Error calling AudioUnitSetProperty -
kAudioUnitProperty_StreamFormat kAudioUnitScope_Input");
+ }
+
+ // Update SR for output
+ err = AudioUnitGetProperty(driver->au_hal,
kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &dstFormat,
&outSize);
+ if (err != noErr) {
+ PERROR("Error calling AudioUnitSetProperty -
kAudioUnitProperty_StreamFormat kAudioUnitScope_Output");
+ }
+ dstFormat.mSampleRate = sampleRate;
+ err = AudioUnitSetProperty(driver->au_hal,
kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &dstFormat,
outSize);
+ if (err != noErr) {
+ PERROR("Error calling AudioUnitSetProperty -
kAudioUnitProperty_StreamFormat kAudioUnitScope_Output");
+ }
+ break;
+ }
+ }
+ return noErr;
+}
+
+
+
int CoreAudioDriver::setup(bool capture, bool playback, const QString &
cardDevice)
{
return -1;
Index: CoreAudioDriver.h
===================================================================
RCS file: /sources/traverso/traverso/src/engine/CoreAudioDriver.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- CoreAudioDriver.h 21 Nov 2008 13:40:16 -0000 1.2
+++ CoreAudioDriver.h 24 Nov 2008 11:17:29 -0000 1.3
@@ -61,12 +61,54 @@
int setup(bool capture=true, bool playback=true, const QString&
cardDevice="none");
-private:
AudioUnit au_hal;
AudioBufferList* input_list;
AudioDeviceID device_id;
int state;
+ channel_t playback_nchannels;
+ channel_t capture_nchannels;
+
+ int xrun_detected;
+ int null_cycle_occured;
+
+
+ void JCALog(char *fmt, ...);
+ void printError(OSStatus err);
+ OSStatus get_device_name_from_id(AudioDeviceID id, char name[256]);
+ OSStatus get_device_id_from_uid(char* UID, AudioDeviceID* id);
+ OSStatus get_default_device(AudioDeviceID * id);
+ OSStatus get_default_input_device(AudioDeviceID* id);
+ OSStatus get_default_output_device(AudioDeviceID* id);
+ OSStatus get_total_channels(AudioDeviceID device, int* channelCount,
bool isInput);
+ OSStatus display_device_names();
+
+ static OSStatus render(void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList *ioData);
+ static OSStatus render_input(
+ void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList *ioData);
+ static OSStatus sr_notification(
+ AudioDeviceID inDevice,
+ UInt32 inChannel,
+ Boolean isInput,
+ AudioDevicePropertyID inPropertyID,
+ void* inClientData);
+ static OSStatus notification(
+ AudioDeviceID inDevice,
+ UInt32 inChannel,
+ Boolean isInput,
+ AudioDevicePropertyID inPropertyID,
+ void* inClientData);
+
};
#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Traverso-commit] traverso/src/engine AudioDevice.h CoreAudioDriv...,
Remon Sijrier <=