mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 01:11:28 +00:00
Implement OGG looping support; musicians rejoice!
Loops are controlled by two tags in the Vorbis Comment, both in PCM samples. LOOP_START holds the beginning of the loop, the position to which playback returns at the end of the loop. LOOP_END is optional; it holds the end of the loop, after which the game seeks to LOOP_START. If undefined, the end of the OGG is the end of the loop. The primary purpose of LOOP_END is if you want to give your file a proper ending for listening outside the game. To preview a looped OGG you have assembled, give it a ".logg" extension and play it using the vgmstream plugin for Winamp or foobar2000. git-svn-id: https://svn.eduke32.com/eduke32@3218 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
6c59071155
commit
1f0693eca4
1 changed files with 51 additions and 9 deletions
|
@ -158,13 +158,27 @@ static playbackstatus MV_GetNextVorbisBlock
|
|||
do {
|
||||
bytes = ov_read(&vd->vf, vd->block + bytesread, BLOCKSIZE - bytesread, 0, 2, 1, &bitstream);
|
||||
//fprintf(stderr, "ov_read = %d\n", bytes);
|
||||
if (bytes > 0) { bytesread += bytes; continue; }
|
||||
if (bytes > 0) {
|
||||
bytesread += bytes;
|
||||
if ((ogg_int64_t)(intptr_t)voice->LoopEnd > 0
|
||||
&& ov_pcm_tell(&vd->vf) >= (ogg_int64_t)(intptr_t)voice->LoopEnd) {
|
||||
err = ov_pcm_seek(&vd->vf,(ogg_int64_t)(intptr_t)voice->LoopStart);
|
||||
if (err != 0) {
|
||||
MV_Printf("MV_GetNextVorbisBlock ov_pcm_seek: LOOP_START %l, LOOP_END %l, err %d\n",
|
||||
(ogg_int64_t)(intptr_t)voice->LoopStart, (ogg_int64_t)(intptr_t)voice->LoopEnd, err);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (bytes == OV_HOLE) continue;
|
||||
else if (bytes == 0) {
|
||||
if (voice->LoopStart) {
|
||||
err = ov_pcm_seek_page(&vd->vf, 0);
|
||||
if (voice->LoopSize > 0) {
|
||||
err = ov_pcm_seek(&vd->vf,(ogg_int64_t)(intptr_t)voice->LoopStart);
|
||||
if (err != 0) {
|
||||
MV_Printf("MV_GetNextVorbisBlock ov_pcm_seek_page_lap: err %d\n", err);
|
||||
MV_Printf("MV_GetNextVorbisBlock ov_pcm_seek: LOOP_START %l, err %d\n",
|
||||
(ogg_int64_t)(intptr_t)voice->LoopStart, err);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
@ -319,8 +333,6 @@ int32_t MV_PlayLoopedVorbis
|
|||
int32_t status;
|
||||
vorbis_data * vd = 0;
|
||||
vorbis_info * vi = 0;
|
||||
|
||||
UNREFERENCED_PARAMETER(loopend);
|
||||
|
||||
if ( !MV_Installed )
|
||||
{
|
||||
|
@ -387,9 +399,39 @@ int32_t MV_PlayLoopedVorbis
|
|||
voice->prev = NULL;
|
||||
voice->priority = priority;
|
||||
voice->callbackval = callbackval;
|
||||
voice->LoopStart = (char *) (intptr_t)(loopstart >= 0 ? TRUE : FALSE);
|
||||
voice->LoopEnd = 0;
|
||||
voice->LoopSize = 0;
|
||||
|
||||
voice->LoopStart = (char *) (intptr_t)(loopstart >= 0 ? loopstart : 0);
|
||||
voice->LoopEnd = (char *) (intptr_t)(loopstart >= 0 && loopend > 0 ? loopend : 0);
|
||||
voice->LoopSize = (loopstart >= 0 ? 1 : 0);
|
||||
|
||||
// load loop tags from metadata
|
||||
if (loopstart < 1)
|
||||
{
|
||||
vorbis_comment * vc = ov_comment(&vd->vf, 0);
|
||||
if (vc != NULL)
|
||||
{
|
||||
char *vc_loopstart = vorbis_comment_query(vc, "LOOP_START", 0);
|
||||
if (vc_loopstart != NULL)
|
||||
{
|
||||
ogg_int64_t ov_loopstart = atol(vc_loopstart);
|
||||
if (ov_loopstart >= 0)
|
||||
{
|
||||
char *vc_loopend = vorbis_comment_query(vc, "LOOP_END", 0);
|
||||
|
||||
voice->LoopStart = (char *) (intptr_t) ov_loopstart;
|
||||
voice->LoopSize = 1;
|
||||
|
||||
if (vc_loopend != NULL)
|
||||
{
|
||||
ogg_int64_t ov_loopend = atol(vc_loopend);
|
||||
if (ov_loopend > 0)
|
||||
voice->LoopEnd = (char *) (intptr_t) ov_loopend;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
voice->Playing = TRUE;
|
||||
voice->Paused = FALSE;
|
||||
|
||||
|
|
Loading…
Reference in a new issue