| 1 |
/* |
| 2 |
* MDAudio.h |
| 3 |
* Alchemusica |
| 4 |
* |
| 5 |
* Created by Toshi Nagata on 08/01/06. |
| 6 |
* Copyright (c) 2008-2016 Toshi Nagata. All rights reserved. |
| 7 |
|
| 8 |
This program is free software; you can redistribute it and/or modify |
| 9 |
it under the terms of the GNU General Public License as published by |
| 10 |
the Free Software Foundation version 2 of the License. |
| 11 |
|
| 12 |
This program is distributed in the hope that it will be useful, |
| 13 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 |
GNU General Public License for more details. |
| 16 |
*/ |
| 17 |
|
| 18 |
#ifndef __MDAudio__ |
| 19 |
#define __MDAudio__ |
| 20 |
|
| 21 |
#include <CoreAudio/CoreAudio.h> |
| 22 |
#include <AudioToolBox/AudioToolbox.h> |
| 23 |
#include <AudioUnit/AudioUnit.h> |
| 24 |
#include "MDAudioUtility.h" |
| 25 |
|
| 26 |
typedef struct MDAudio MDAudio; |
| 27 |
|
| 28 |
#define CHECK_ERR(var, funcall) do { var = (funcall); if (var) { MDAudioShowError(var, __FILE__, __LINE__); goto exit; } } while (0) |
| 29 |
|
| 30 |
// CoreAudio specific |
| 31 |
typedef AudioStreamBasicDescription MDAudioFormat; |
| 32 |
typedef AudioDeviceID MDAudioDeviceID; |
| 33 |
|
| 34 |
enum { |
| 35 |
kMDAudioDeviceUnknown = kAudioDeviceUnknown |
| 36 |
}; |
| 37 |
|
| 38 |
#define kMDAudioMusicDeviceUnknown ((UInt64)0) |
| 39 |
|
| 40 |
enum { |
| 41 |
kMDAudioFileAIFFType = kAudioFileAIFFType, |
| 42 |
kMDAudioFileWAVType = kAudioFileWAVEType |
| 43 |
}; |
| 44 |
|
| 45 |
/* Cached information for the hardware audio devices */ |
| 46 |
typedef struct MDAudioDeviceInfo { |
| 47 |
char *name; /* malloc'ed */ |
| 48 |
MDAudioDeviceID deviceID; |
| 49 |
SInt16 nChannels; |
| 50 |
SInt16 flags; /* For internal use */ |
| 51 |
UInt32 safetyOffset; |
| 52 |
UInt32 bufferSizeFrames; |
| 53 |
MDAudioFormat format; |
| 54 |
} MDAudioDeviceInfo; |
| 55 |
|
| 56 |
enum { |
| 57 |
kMDAudioHasCocoaView = 1, |
| 58 |
kMDAudioHasCarbonView = 2 |
| 59 |
}; |
| 60 |
|
| 61 |
/* Cached information for Music Devices (software synthesizers) */ |
| 62 |
/* Also used for audio effects */ |
| 63 |
typedef struct MDAudioMusicDeviceInfo { |
| 64 |
UInt64 code; /* SubType and Manufacturer */ |
| 65 |
char *name; /* malloc'ed */ |
| 66 |
MDAudioFormat format; |
| 67 |
unsigned char hasCustomView; |
| 68 |
unsigned char acceptsCanonicalFormat; /* For effects */ |
| 69 |
} MDAudioMusicDeviceInfo; |
| 70 |
|
| 71 |
#define kMDAudioNumberOfInputStreams 40 |
| 72 |
#define kMDAudioNumberOfOutputStreams 1 |
| 73 |
#define kMDAudioNumberOfStreams (kMDAudioNumberOfInputStreams + kMDAudioNumberOfOutputStreams) |
| 74 |
#define kMDAudioFirstIndexForOutputStream kMDAudioNumberOfInputStreams |
| 75 |
#define kMDAudioMusicDeviceIndexOffset 1000 |
| 76 |
|
| 77 |
#define kMDAudioMaxMIDIBytesToSendPerDevice 4096 |
| 78 |
#define kMDAudioMIDIBufferSize (kMDAudioMaxMIDIBytesToSendPerDevice * 8) |
| 79 |
|
| 80 |
/* Audio Effect Instance */ |
| 81 |
typedef struct MDAudioEffect { |
| 82 |
char *name; /* malloc'ed */ |
| 83 |
float xpos; /* X position in the layout view */ |
| 84 |
float width; /* Width in the layout view */ |
| 85 |
int effectDeviceIndex; /* Index to gAudio->effectDeviceInfos */ |
| 86 |
AudioUnit unit; /* Effect unit */ |
| 87 |
AUNode node; /* AUGraph node containing the effect unit */ |
| 88 |
AudioUnit converterUnit; /* Converter unit (optional) */ |
| 89 |
AUNode converterNode; |
| 90 |
} MDAudioEffect; |
| 91 |
|
| 92 |
/* Audio Effect Chain (for a single stereo signal) */ |
| 93 |
typedef struct MDAudioEffectChain { |
| 94 |
AudioUnit converterUnit; /* Converter unit (used at the mixer input if necessary) */ |
| 95 |
AUNode converterNode; |
| 96 |
int alive; /* Non-zero if this chain is working */ |
| 97 |
int neffects; |
| 98 |
MDAudioEffect *effects; |
| 99 |
} MDAudioEffectChain; |
| 100 |
|
| 101 |
/* Cached information for audio input (up to 40) and output (one). */ |
| 102 |
typedef struct MDAudioIOStreamInfo { |
| 103 |
|
| 104 |
int deviceIndex; /* -1: none, 0-999: {input|output}DeviceInfos, 1000-: musicDeviceInfos */ |
| 105 |
int busIndex; /* The bus number (redundant, but useful in the callback) */ |
| 106 |
UInt64 deviceID; /* UInt64 for music device; AudioDeviceID for audio device */ |
| 107 |
|
| 108 |
AudioUnit unit; /* AUHAL or MusicDevice */ |
| 109 |
AUNode node; /* Node in the AUGraph */ |
| 110 |
AudioUnit converterUnit; /* Converter unit (for MusicDevice) */ |
| 111 |
AUNode converterNode; |
| 112 |
|
| 113 |
/* Effects */ |
| 114 |
AudioUnit effectMixerUnit; /* Mixer for effect outputs (only for nchains>=2) */ |
| 115 |
AUNode effectMixerNode; |
| 116 |
int nchains; |
| 117 |
MDAudioEffectChain *chains; |
| 118 |
|
| 119 |
float pan; |
| 120 |
float volume; |
| 121 |
MDAudioFormat format; /* Audio format for the unit */ |
| 122 |
|
| 123 |
/* for input AUHAL only */ |
| 124 |
AudioBufferList *bufferList; /* Buffer for getting audio signal from AUHAL */ |
| 125 |
MDRingBuffer *ring; /* Ring buffer for feeding the mixer input */ |
| 126 |
MDSampleTime firstInputTime; /* Time stamp for audio signal input */ |
| 127 |
MDSampleTime firstOutputTime; /* Time stamp for audio siganl output */ |
| 128 |
MDSampleTime inToOutSampleOffset; /* Time stamp offset */ |
| 129 |
SInt32 bufferSizeFrames; /* buffer size */ |
| 130 |
|
| 131 |
/* for MusicDevice only */ |
| 132 |
char *midiControllerName; /* malloc'ed */ |
| 133 |
unsigned char *midiBuffer; /* Ring buffer for MIDI scheduling */ |
| 134 |
int32_t midiBufferWriteOffset; |
| 135 |
int32_t midiBufferReadOffset; |
| 136 |
int32_t sysexLength; |
| 137 |
unsigned char *sysexData; |
| 138 |
int32_t requestFlush; |
| 139 |
} MDAudioIOStreamInfo; |
| 140 |
|
| 141 |
MDStatus MDAudioInitialize(void); |
| 142 |
MDStatus MDAudioDispose(void); |
| 143 |
int MDAudioShowError(OSStatus sts, const char *file, int line); |
| 144 |
|
| 145 |
//MDAudio * MDAudioNew(void); |
| 146 |
//void MDAudioRelease(MDAudio *inAudio); |
| 147 |
|
| 148 |
MDStatus MDAudioUpdateDeviceInfo(void); |
| 149 |
int MDAudioDeviceCountInfo(int isInput); |
| 150 |
MDAudioDeviceInfo *MDAudioDeviceInfoAtIndex(int idx, int isInput); |
| 151 |
MDAudioDeviceInfo *MDAudioDeviceInfoForDeviceID(int deviceID, int isInput, int *deviceIndex); |
| 152 |
MDAudioDeviceInfo *MDAudioDeviceInfoWithName(const char *name, int isInput, int *deviceIndex); |
| 153 |
int MDAudioMusicDeviceCountInfo(void); |
| 154 |
MDAudioMusicDeviceInfo *MDAudioMusicDeviceInfoAtIndex(int idx); |
| 155 |
MDAudioMusicDeviceInfo *MDAudioMusicDeviceInfoForCode(UInt64 code, int *outIndex); |
| 156 |
int MDAudioEffectDeviceCountInfo(void); |
| 157 |
MDAudioMusicDeviceInfo *MDAudioEffectDeviceInfoAtIndex(int idx); |
| 158 |
MDAudioMusicDeviceInfo *MDAudioEffectDeviceInfoForCode(UInt64 code, int *outIndex); |
| 159 |
|
| 160 |
MDAudioIOStreamInfo *MDAudioGetIOStreamInfoAtIndex(int idx); |
| 161 |
int MDAudioScheduleMIDIToStream(MDAudioIOStreamInfo *ip, UInt64 timeStamp, int length, unsigned char *midiData, int isSysEx); |
| 162 |
|
| 163 |
/* idx: 0-(kMDAudioNumberOfInputStreams-1)...input, kMDAudioFirstIndexForOutputStream...output */ |
| 164 |
/* deviceIndex: -1: none, 0-999: {input|output}DeviceInfos, 1000-: musicDeviceInfos */ |
| 165 |
MDStatus MDAudioSelectIOStreamDevice(int idx, int deviceIndex); |
| 166 |
MDStatus MDAudioGetIOStreamDevice(int idx, int *outDeviceIndex); |
| 167 |
MDStatus MDAudioGetMixerBusAttributes(int idx, float *outPan, float *outVolume, float *outAmpLeft, float *outAmpRight, float *outPeakLeft, float *outPeakRight); |
| 168 |
MDStatus MDAudioSetMixerVolume(int idx, float volume); |
| 169 |
MDStatus MDAudioSetMixerPan(int idx, float pan); |
| 170 |
|
| 171 |
MDStatus MDAudioAppendEffectChain(int streamIndex); |
| 172 |
MDStatus MDAudioRemoveLastEffectChain(int streamIndex); |
| 173 |
MDStatus MDAudioChangeEffect(int streamIndex, int chainIndex, int effectIndex, int effectID, int insert); |
| 174 |
MDStatus MDAudioRemoveEffect(int streamIndex, int chainIndex, int effectIndex); |
| 175 |
|
| 176 |
/*MDStatus MDAudioStartInput(void); |
| 177 |
MDStatus MDAudioStopInput(void); */ |
| 178 |
/*MDStatus MDAudioEnablePlayThru(int flag); |
| 179 |
int MDAudioIsPlayThruEnabled(void); */ |
| 180 |
|
| 181 |
MDStatus MDAudioPrepareRecording(const char *filename, const MDAudioFormat *format, int audioFileType, UInt64 recordingDuration); |
| 182 |
MDStatus MDAudioStartRecording(void); |
| 183 |
MDStatus MDAudioStopRecording(void); |
| 184 |
int MDAudioIsRecording(void); |
| 185 |
|
| 186 |
//MDStatus MDAudioPrepareRecording(MDAudio *inAudio, MDAudioDeviceID deviceID, const char *filename, const MDAudioFormat *format, int audioFileType); |
| 187 |
//MDStatus MDAudioStartRecording(MDAudio *inAudio); |
| 188 |
//MDStatus MDAudioStop(MDAudio *inAudio); |
| 189 |
//MDStatus MDAudioStopRecording(MDAudio *inAudio); |
| 190 |
//int MDAudioIsRecording(MDAudio *inAudio); |
| 191 |
//MDArray * MDAudioGetDeviceInfo(int isInput); |
| 192 |
//MDAudioDeviceID MDAudioDeviceWithName(const char *name, int isInput); |
| 193 |
|
| 194 |
void MDAudioFormatSetCanonical(MDAudioFormat *fmt, float sampleRate, int nChannels, int interleaved); |
| 195 |
|
| 196 |
#endif |