[Commits] SDL_mixer: Better fix for looping on Mac OS X. This also gives ...
libsdl.org revision control
commits-owner at libsdl.org
Sun Jan 1 13:48:51 PST 2012
details: http://hg.libsdl.org/SDL_mixer/rev/f19368c22ebd
changeset: 533:f19368c22ebd
user: Sam Lantinga <slouken at libsdl.org>
date: Sun Jan 01 16:45:58 2012 -0500
description:
Better fix for looping on Mac OS X. This also gives event perfect looping on Windows and theoretically on Haiku.
diffstat:
music.c | 29 +++++++++++------------
native_midi/native_midi.h | 3 +-
native_midi/native_midi_haiku.cpp | 36 +++++++++++++++-------------
native_midi/native_midi_mac.c | 11 +++-----
native_midi/native_midi_macosx.c | 22 +++++++++--------
native_midi/native_midi_win32.c | 48 ++++++++++++++++++++++----------------
6 files changed, 78 insertions(+), 71 deletions(-)
diffs (369 lines):
diff -r b8e8ae4852b2 -r f19368c22ebd music.c
--- a/music.c Sun Jan 01 14:40:22 2012 -0500
+++ b/music.c Sun Jan 01 16:45:58 2012 -0500
@@ -199,10 +199,17 @@
if (!music_internal_playing())
{
+ /* Native MIDI handles looping internally */
+ if (music_playing->type == MUS_MID && native_midi_ok) {
+ music_loops = 0;
+ }
+
/* Restart music if it has to loop at a high level */
- if (music_loops && --music_loops)
+ if (music_loops)
{
- Mix_Fading current_fade = music_playing->fading;
+ Mix_Fading current_fade;
+ --music_loops;
+ current_fade = music_playing->fading;
music_internal_play(music_playing, 0.0);
music_playing->fading = current_fade;
}
@@ -791,7 +798,7 @@
case MUS_MID:
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
- native_midi_start(music->data.nativemidi);
+ native_midi_start(music->data.nativemidi, music_loops);
goto skip;
}
#endif
@@ -889,6 +896,10 @@
SDL_LockAudio();
}
music_active = 1;
+ if (loops == 1) {
+ /* Loop is the number of times to play the audio */
+ loops = 0;
+ }
music_loops = loops;
retval = music_internal_play(music, position);
SDL_UnlockAudio();
@@ -920,18 +931,6 @@
MOD_jump_to_time(music_playing->data.module, position);
break;
#endif
-#ifdef MID_MUSIC
- case MUS_MID:
-#ifdef USE_NATIVE_MIDI
- if ( native_midi_ok ) {
- retval = native_midi_jump_to_time(music_playing->data.nativemidi, position);
- break;
- }
-#endif
- /* TODO: Implement this for other music backends */
- retval = -1;
- break;
-#endif
#ifdef OGG_MUSIC
case MUS_OGG:
OGG_jump_to_time(music_playing->data.ogg, position);
diff -r b8e8ae4852b2 -r f19368c22ebd native_midi/native_midi.h
--- a/native_midi/native_midi.h Sun Jan 01 14:40:22 2012 -0500
+++ b/native_midi/native_midi.h Sun Jan 01 16:45:58 2012 -0500
@@ -30,8 +30,7 @@
NativeMidiSong *native_midi_loadsong(const char *midifile);
NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw, int freerw);
void native_midi_freesong(NativeMidiSong *song);
-void native_midi_start(NativeMidiSong *song);
-int native_midi_jump_to_time(NativeMidiSong *song, double time);
+void native_midi_start(NativeMidiSong *song, int loops);
void native_midi_stop();
int native_midi_active();
void native_midi_setvolume(int volume);
diff -r b8e8ae4852b2 -r f19368c22ebd native_midi/native_midi_haiku.cpp
--- a/native_midi/native_midi_haiku.cpp Sun Jan 01 14:40:22 2012 -0500
+++ b/native_midi/native_midi_haiku.cpp Sun Jan 01 16:45:58 2012 -0500
@@ -45,6 +45,7 @@
MidiEventsStore()
{
fPlaying = false;
+ fLoops = 0;
}
virtual status_t Import(SDL_RWops *rw)
{
@@ -66,8 +67,16 @@
MIDIEvent *ev = fEvs;
uint32 startTime = B_NOW;
- while (KeepRunning() && ev)
+ while (KeepRunning())
{
+ if (!ev) {
+ if (fLoops && fEvs) {
+ --fLoops;
+ fPos = 0;
+ ev = fEvs;
+ } else
+ break;
+ }
SprayEvent(ev, ev->time + startTime);
ev = ev->next;
fPos++;
@@ -82,25 +91,22 @@
fEvs = 0;
}
- int CurrentEvent()
- {
- return fPos;
- }
- int CountEvents()
- {
- return fTotal;
- }
-
bool IsPlaying()
{
return fPlaying;
}
+ void SetLoops(int loops)
+ {
+ fLoops = loops;
+ }
+
protected:
MIDIEvent *fEvs;
Uint16 fDivision;
int fPos, fTotal;
+ int fLoops;
bool fPlaying;
void SprayEvent(MIDIEvent *ev, uint32 time)
@@ -251,18 +257,14 @@
delete song->store;
delete song; song = 0;
}
-void native_midi_start(NativeMidiSong *song)
+void native_midi_start(NativeMidiSong *song, int loops)
{
native_midi_stop();
song->store->Connect(&synth);
+ song->store->SetLoops(loops);
song->store->Start();
currentSong = song;
}
-int native_midi_jump_to_time(NativeMidiSong *song, double time)
-{
- /* Not yet implemented */
- return -1;
-}
void native_midi_stop()
{
if (currentSong == NULL) return;
@@ -275,7 +277,7 @@
int native_midi_active()
{
if (currentSong == NULL) return 0;
- return currentSong->store->CurrentEvent() < currentSong->store->CountEvents();
+ return currentSong->store->IsPlaying();
}
const char* native_midi_error(void)
diff -r b8e8ae4852b2 -r f19368c22ebd native_midi/native_midi_mac.c
--- a/native_midi/native_midi_mac.c Sun Jan 01 14:40:22 2012 -0500
+++ b/native_midi/native_midi_mac.c Sun Jan 01 16:45:58 2012 -0500
@@ -192,12 +192,15 @@
}
}
-void native_midi_start(NativeMidiSong *song)
+void native_midi_start(NativeMidiSong *song, int loops)
{
UInt32 queueFlags = 0;
ComponentResult tpError;
assert (gTunePlayer != NULL);
+
+ /* FIXME: is this code even used anymore? */
+ assert (loops == 0);
SDL_PauseAudio(1);
SDL_UnlockAudio();
@@ -254,12 +257,6 @@
SDL_PauseAudio(0);
}
-int native_midi_jump_to_time(NativeMidiSong *song, double time)
-{
- /* Not yet implemented */
- return -1;
-}
-
void native_midi_stop()
{
if (gTunePlayer == NULL)
diff -r b8e8ae4852b2 -r f19368c22ebd native_midi/native_midi_macosx.c
--- a/native_midi/native_midi_macosx.c Sun Jan 01 14:40:22 2012 -0500
+++ b/native_midi/native_midi_macosx.c Sun Jan 01 16:45:58 2012 -0500
@@ -41,6 +41,7 @@
MusicSequence sequence;
MusicTimeStamp endTime;
AudioUnit audiounit;
+ int loops;
};
static NativeMidiSong *currentsong = NULL;
@@ -250,7 +251,7 @@
}
}
-void native_midi_start(NativeMidiSong *song)
+void native_midi_start(NativeMidiSong *song, int loops)
{
int vol;
@@ -264,6 +265,7 @@
MusicPlayerStop(currentsong->player);
currentsong = song;
+ currentsong->loops = loops;
MusicPlayerPreroll(song->player);
MusicPlayerSetTime(song->player, 0);
@@ -279,13 +281,6 @@
SDL_PauseAudio(0);
}
-int native_midi_jump_to_time(NativeMidiSong *song, double time)
-{
- if (MusicPlayerSetTime(song->player, time) != noErr)
- return -1;
- return 0;
-}
-
void native_midi_stop()
{
if (currentsong) {
@@ -305,8 +300,15 @@
return 0;
MusicPlayerGetTime(currentsong->player, ¤tTime);
- return ((currentTime < currentsong->endTime) ||
- (currentTime >= kMusicTimeStamp_EndOfTrack));
+ if ((currentTime < currentsong->endTime) ||
+ (currentTime >= kMusicTimeStamp_EndOfTrack)) {
+ return 1;
+ } else if (currentsong->loops) {
+ --currentsong->loops;
+ MusicPlayerSetTime(currentsong->player, 0);
+ return 1;
+ }
+ return 0;
}
void native_midi_setvolume(int volume)
diff -r b8e8ae4852b2 -r f19368c22ebd native_midi/native_midi_win32.c
--- a/native_midi/native_midi_win32.c Sun Jan 01 14:40:22 2012 -0500
+++ b/native_midi/native_midi_win32.c Sun Jan 01 16:45:58 2012 -0500
@@ -36,9 +36,11 @@
struct _NativeMidiSong {
int MusicLoaded;
int MusicPlaying;
- MIDIHDR MidiStreamHdr;
+ int Loops;
+ int CurrentHdr;
+ MIDIHDR MidiStreamHdr[2];
MIDIEVENT *NewEvents;
- Uint16 ppqn;
+ Uint16 ppqn;
int Size;
int NewPos;
};
@@ -51,11 +53,14 @@
{
MMRESULT err;
int BlockSize;
+ MIDIHDR *hdr;
if ((song->MusicLoaded) && (song->NewEvents))
{
- // proff 12/8/98: Added for savety
- midiOutUnprepareHeader((HMIDIOUT)hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR));
+ // proff 12/8/98: Added for safety
+ song->CurrentHdr = !song->CurrentHdr;
+ hdr = &song->MidiStreamHdr[song->CurrentHdr];
+ midiOutUnprepareHeader((HMIDIOUT)hMidiStream,hdr,sizeof(MIDIHDR));
if (song->NewPos>=song->Size)
return 0;
BlockSize=(song->Size-song->NewPos);
@@ -63,15 +68,16 @@
return 0;
if (BlockSize>36000)
BlockSize=36000;
- song->MidiStreamHdr.lpData=(void *)((unsigned char *)song->NewEvents+song->NewPos);
+ hdr->lpData=(void *)((unsigned char *)song->NewEvents+song->NewPos);
song->NewPos+=BlockSize;
- song->MidiStreamHdr.dwBufferLength=BlockSize;
- song->MidiStreamHdr.dwBytesRecorded=BlockSize;
- song->MidiStreamHdr.dwFlags=0;
- err=midiOutPrepareHeader((HMIDIOUT)hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR));
+ hdr->dwBufferLength=BlockSize;
+ hdr->dwBytesRecorded=BlockSize;
+ hdr->dwFlags=0;
+ hdr->dwOffset=0;
+ err=midiOutPrepareHeader((HMIDIOUT)hMidiStream,hdr,sizeof(MIDIHDR));
if (err!=MMSYSERR_NOERROR)
return 0;
- err=midiStreamOut(hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR));
+ err=midiStreamOut(hMidiStream,hdr,sizeof(MIDIHDR));
return 0;
}
return 1;
@@ -163,12 +169,19 @@
switch( uMsg )
{
case MOM_DONE:
- if ((currentsong->MusicLoaded) && (dwParam1 == (DWORD_PTR)¤tsong->MidiStreamHdr))
+ if ((currentsong->MusicLoaded) && (dwParam1 == (DWORD_PTR)¤tsong->MidiStreamHdr[currentsong->CurrentHdr]))
BlockOut(currentsong);
break;
case MOM_POSITIONCB:
- if ((currentsong->MusicLoaded) && (dwParam1 == (DWORD_PTR)¤tsong->MidiStreamHdr))
- currentsong->MusicPlaying=0;
+ if ((currentsong->MusicLoaded) && (dwParam1 == (DWORD_PTR)¤tsong->MidiStreamHdr[currentsong->CurrentHdr])) {
+ if (currentsong->Loops) {
+ --currentsong->Loops;
+ currentsong->NewPos=0;
+ BlockOut(currentsong);
+ } else {
+ currentsong->MusicPlaying=0;
+ }
+ }
break;
default:
break;
@@ -249,7 +262,7 @@
}
}
-void native_midi_start(NativeMidiSong *song)
+void native_midi_start(NativeMidiSong *song, int loops)
{
MMRESULT merr;
MIDIPROPTIMEDIV mptd;
@@ -267,6 +280,7 @@
currentsong=song;
currentsong->NewPos=0;
currentsong->MusicPlaying=1;
+ currentsong->Loops=loops;
mptd.cbStruct=sizeof(MIDIPROPTIMEDIV);
mptd.dwTimeDiv=currentsong->ppqn;
merr=midiStreamProperty(hMidiStream,(LPBYTE)&mptd,MIDIPROP_SET | MIDIPROP_TIMEDIV);
@@ -275,12 +289,6 @@
}
}
-int native_midi_jump_to_time(NativeMidiSong *song, double time)
-{
- /* Not yet implemented */
- return -1;
-}
-
void native_midi_stop()
{
if (!hMidiStream)
More information about the commits
mailing list