Skip to content

Commit

Permalink
Added volume control to Mac OS X Core MIDI native midi backend.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Oct 19, 2009
1 parent c6fab84 commit d8d4fd2
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 11 deletions.
2 changes: 1 addition & 1 deletion configure.in
Expand Up @@ -284,7 +284,7 @@ AC_HELP_STRING([--enable-music-native-midi], [enable native MIDI music output [[
;;
*-*-darwin*)
use_music_native_midi=yes
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AudioToolbox -Wl,-framework,CoreServices"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,CoreServices"
;;
esac
if test x$use_music_native_midi = xyes; then
Expand Down
94 changes: 84 additions & 10 deletions native_midi/native_midi_macosx.c
Expand Up @@ -27,8 +27,10 @@

#if __MACOSX__

#include <Carbon/Carbon.h>
#include <AudioToolbox/AudioToolbox.h>

#include "../SDL_mixer.h"
#include "SDL_endian.h"
#include "native_midi.h"

Expand All @@ -38,9 +40,11 @@ struct _NativeMidiSong
MusicPlayer player;
MusicSequence sequence;
MusicTimeStamp endTime;
AudioUnit audiounit;
};

static NativeMidiSong *currentsong = NULL;
static int latched_volume = MIX_MAX_VOLUME;

static OSStatus
GetSequenceLength(MusicSequence sequence, MusicTimeStamp *_sequenceLength)
Expand Down Expand Up @@ -80,6 +84,61 @@ GetSequenceLength(MusicSequence sequence, MusicTimeStamp *_sequenceLength)
}


/* we're looking for the sequence output audiounit. */
static OSStatus
GetSequenceAudioUnit(MusicSequence sequence, AudioUnit *aunit)
{
AUGraph graph;
UInt32 nodecount, i;
OSStatus err;

err = MusicSequenceGetAUGraph(sequence, &graph);
if (err != noErr)
return err;

err = AUGraphGetNodeCount(graph, &nodecount);
if (err != noErr)
return err;

for (i = 0; i < nodecount; i++) {
AUNode node;

if (AUGraphGetIndNode(graph, i, &node) != noErr)
continue; /* better luck next time. */

#if 1 /* this is deprecated, but works back to 10.0 */
{
struct ComponentDescription desc;
UInt32 classdatasize = 0;
void *classdata = NULL;
err = AUGraphGetNodeInfo(graph, node, &desc, &classdatasize,
&classdata, aunit);
if (err != noErr)
continue;
else if (desc.componentType != kAudioUnitType_Output)
continue;
else if (desc.componentSubType != kAudioUnitSubType_DefaultOutput)
continue;
}
#else /* not deprecated, but requires 10.5 or later */
{
AudioComponentDescription desc;
if (AUGraphNodeInfo(graph, node, &desc, aunit) != noErr)
continue;
else if (desc.componentType != kAudioUnitType_Output)
continue;
else if (desc.componentSubType != kAudioUnitSubType_DefaultOutput)
continue;
}
#endif

return noErr; /* found it! */
}

return kAUGraphErr_NodeNotFound;
}


int native_midi_detect()
{
return 1; /* always available. */
Expand Down Expand Up @@ -188,31 +247,39 @@ void native_midi_freesong(NativeMidiSong *song)

void native_midi_start(NativeMidiSong *song)
{
int vol;

if (song == NULL)
return;

SDL_PauseAudio(1);
SDL_UnlockAudio();
SDL_PauseAudio(1);
SDL_UnlockAudio();

if (currentsong)
MusicPlayerStop(currentsong->player);

currentsong = song;
MusicPlayerStart(song->player);

SDL_LockAudio();
SDL_PauseAudio(0);
GetSequenceAudioUnit(song->sequence, &song->audiounit);

vol = latched_volume;
latched_volume++; /* just make this not match. */
native_midi_setvolume(vol);

SDL_LockAudio();
SDL_PauseAudio(0);
}

void native_midi_stop()
{
if (currentsong) {
SDL_PauseAudio(1);
SDL_UnlockAudio();
SDL_PauseAudio(1);
SDL_UnlockAudio();
MusicPlayerStop(currentsong->player);
currentsong = NULL;
SDL_LockAudio();
SDL_PauseAudio(0);
SDL_LockAudio();
SDL_PauseAudio(0);
}
}

Expand All @@ -229,8 +296,15 @@ int native_midi_active()

void native_midi_setvolume(int volume)
{
/* !!! FIXME: call MusicSequenceGetAUGraph(), figure out where the output
!!! FIXME: audio unit is, and change its gain */
if (latched_volume == volume)
return;

latched_volume = volume;
if ((currentsong) && (currentsong->audiounit)) {
const float floatvol = ((float) volume) / ((float) MIX_MAX_VOLUME);
AudioUnitSetParameter(currentsong->audiounit, kHALOutputParam_Volume,
kAudioUnitScope_Global, 0, floatvol, 0);
}
}

const char *native_midi_error(void)
Expand Down

0 comments on commit d8d4fd2

Please sign in to comment.