Ich versuche mir ein Framework für das Abspielen von Musikdaten zu basteln. Das Definieren und Abspielen von Musikdaten ist mir soweit klar. Nur das Unlocken muss noch gekärt werden.
In einer Methode / Funktion übergebe ich einen optr mit dem Namen music von meinem Chunk mit den Musikdaten:
word *p_music;
MemLock(OptrToHandle(music));
p_music = LMemDeref(music);
SoundAllocMusic(p_music, 4, &g_songHandle);
SoundPlayMusic(g_songHandle, SP_STANDARD + SP_IMMEDIATE, EIGHTH, UNLOCK_ON_EOS);
Die Funktion SoundPlayMusic erwartet, dass der Chunk music die ganze Zeit gelockt ist. Das UNLOCK_ON_EOS macht dies laut meinen Tests nicht.
Es stellt sich jetzt die Frage, wie ich denn mitbekomme, wenn das Abspielen der Muskdaten fertig ist. Hierzu könnte man meiner Meinung nach die Möglichkeit der Notifikation innerhalb der Musikdaten benutzen:
/*
; GE_SEND_NOTIFICATION causes the stream to send
; a given message to a given object. The message
; will be placed at the end of the queue.
;
; USAGE :: GE_SEND_NOTIFICATION <word message>
; <object handle> <object chunk>
*/
Das sieht dann so aus:
@chunk word DemoSong[] = {
SSE_CHANGE, 0, IP_LEAD_0, IT_STANDARD_TABLE,
...
SSE_GENERAL, GE_SEND_NOTIFICATION, MSG_SND_STOP_SELF, 0, 0,
SSE_GENERAL, GE_END_OF_SONG
// SSE_GENERAL, GE_SEND_NOTIFICATION, MSG_SND_STOP_SONG, OptrToHandle(process), OptrToChunk(process),
// SSE_GENERAL, GE_SEND_NOTIFICATION, MSG_SND_STOP_SELF, OptrToHandle(oself), OptrToChunk(oself),
// SSE_GENERAL, GE_SEND_NOTIFICATION, MSG_SND_STOP_SELF, OptrToHandle(@SoundControl), OptrToChunk(@SoundControl),
};
Leider kann ich in einem "statischen" Chunk die Werte für das Objekt nicht hinterlegen. Diese sind ja erst zur Laufzeit bekannt. Darum sind beide mit 0 angegeben und die Idee ist nun, dies zur Laufzeit zu patchen.
e = LMemGetChunkSize(music);
*(p_music + e - 4) = (word) OptrToHandle(@SoundControl);
*(p_music + e - 3) = (word) OptrToChunk(@SoundControl);
SoundControl ist ein generisches Objekt (MetaClass) und nur dafür gedacht, diese Meldung zu erhalten. Habe das kurz anprobiert, aber leider noch ohne Erfolg.
Was denkt Ihr? Macht das Sinn? Seht Ihr andere Möglichkeiten?