1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| //
// Music.cpp
// test26
//
// Created by Lion User on 14/03/13.
// Copyright (c) 2013 Lion User. All rights reserved.
//
#ifdef _cplusplus
#include "Music.h"
#include <CoreServices/CoreServices.h> //for file stuff
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h> //for AUGraph
#include <unistd.h> // used for usleep...
// This call creates the Graph and the Synth unit...
OSStatus CreateAUGraph (AUGraph &outGraph, AudioUnit &outSynth)
{
OSStatus result;
//create the nodes of the graph
AUNode synthNode, limiterNode, outNode;
AudioComponentDescription cd;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
cd.componentFlags = 0;
cd.componentFlagsMask = 0;
require_noerr (result = NewAUGraph (&outGraph), home);
cd.componentType = kAudioUnitType_MusicDevice;
cd.componentSubType = kAudioUnitSubType_DLSSynth;
require_noerr (result = AUGraphAddNode (outGraph, &cd, &synthNode), home);
cd.componentType = kAudioUnitType_Effect;
cd.componentSubType = kAudioUnitSubType_PeakLimiter;
require_noerr (result = AUGraphAddNode (outGraph, &cd, &limiterNode), home);
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_DefaultOutput;
require_noerr (result = AUGraphAddNode (outGraph, &cd, &outNode), home);
require_noerr (result = AUGraphOpen (outGraph), home);
require_noerr (result = AUGraphConnectNodeInput (outGraph, synthNode, 0, limiterNode, 0), home);
require_noerr (result = AUGraphConnectNodeInput (outGraph, limiterNode, 0, outNode, 0), home);
// ok we're good to go - get the Synth Unit...
require_noerr (result = AUGraphNodeInfo(outGraph, synthNode, 0, &outSynth), home);
home:
return result;
}
// some MIDI constants:
enum {
kMidiMessage_ControlChange = 0xB,
kMidiMessage_ProgramChange = 0xC,
kMidiMessage_BankMSBControl = 0,
kMidiMessage_BankLSBControl = 32,
kMidiMessage_NoteOn = 0x9
};
int test() {
AUGraph graph = 0;
AudioUnit synthUnit;
OSStatus result;
char* bankPath = 0;
UInt8 midiChannelInUse = 0; //we're using midi channel 1...
// this is the only option to main that we have...
// just the full path of the sample bank...
// On OS X there are known places were sample banks can be stored
// Library/Audio/Sounds/Banks - so you could scan this directory and give the user options
// about which sample bank to use...
//if (argc > 1) bankPath = const_cast<char*>(argv[1]);
require_noerr (result = CreateAUGraph (graph, synthUnit), home);
// if the user supplies a sound bank, we'll set that before we initialize and start playing
if (bankPath)
{
FSRef fsRef;
require_noerr (result = FSPathMakeRef ((const UInt8*)bankPath, &fsRef, 0), home);
printf ("Setting Sound Bank:%s\n", bankPath);
require_noerr (result = AudioUnitSetProperty (synthUnit,
kMusicDeviceProperty_SoundBankFSRef,
kAudioUnitScope_Global, 0,
&fsRef, sizeof(fsRef)), home);
}
// ok we're set up to go - initialize and start the graph
require_noerr (result = AUGraphInitialize (graph), home);
//set our bank
require_noerr (result = MusicDeviceMIDIEvent(synthUnit,
kMidiMessage_ControlChange << 4 | midiChannelInUse,
kMidiMessage_BankMSBControl, 0,
0/*sample offset*/), home);
require_noerr (result = MusicDeviceMIDIEvent(synthUnit,
kMidiMessage_ProgramChange << 4 | midiChannelInUse,
0/*prog change num*/, 0,
0/*sample offset*/), home);
CAShow (graph); // prints out the graph so we can see what it looks like...
require_noerr (result = AUGraphStart (graph), home);
// we're going to play an octave of MIDI notes: one a second
for (int i = 0; i < 4; i++) {
//UInt32 noteNum = i + 60;
UInt32 onVelocity = 127;
UInt32 noteOnCommand = kMidiMessage_NoteOn << 4 | midiChannelInUse;
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, 60, onVelocity, 0), home);
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, 65, onVelocity, 0), home);
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, 68, onVelocity, 0), home);
// sleep for a second
usleep (1 * 1000 * 1000);
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, 60, 0, 0), home);
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, 65, 0, 0), home);
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, 68, 0, 0), home);
}
// ok we're done now
home:
if (graph) {
AUGraphStop (graph); // stop playback - AUGraphDispose will do that for us but just showing you what to do
DisposeAUGraph (graph);
}
return result;
}
#endif |
Partager