Implemented more stringent loop checking in ft2play

CQTexperiment
Chris Moeller 2014-09-14 17:51:48 -07:00
parent a7671023c4
commit cb1a699647
4 changed files with 243 additions and 17 deletions

View File

@ -13,6 +13,8 @@
839CAC4018DA746000D67EA9 /* ft2play.c in Sources */ = {isa = PBXBuildFile; fileRef = 839CAC3F18DA746000D67EA9 /* ft2play.c */; };
83EAF76818E8F70400C896A6 /* dbopl.c in Sources */ = {isa = PBXBuildFile; fileRef = 83EAF76618E8F70400C896A6 /* dbopl.c */; };
83EAF76918E8F70400C896A6 /* dbopl.h in Headers */ = {isa = PBXBuildFile; fileRef = 83EAF76718E8F70400C896A6 /* dbopl.h */; };
83F1529419C667000000856F /* barray.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F1529219C667000000856F /* barray.h */; };
83F1529519C667000000856F /* barray.c in Sources */ = {isa = PBXBuildFile; fileRef = 83F1529319C667000000856F /* barray.c */; };
83F4D54818D82105009B2DE6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 83F4D54618D82105009B2DE6 /* InfoPlist.strings */; };
83F4D57718D821D2009B2DE6 /* st3play.c in Sources */ = {isa = PBXBuildFile; fileRef = 83F4D57318D821D2009B2DE6 /* st3play.c */; };
83F4D57818D821D2009B2DE6 /* st3play.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F4D57418D821D2009B2DE6 /* st3play.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -25,6 +27,8 @@
839CAC3F18DA746000D67EA9 /* ft2play.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ft2play.c; sourceTree = "<group>"; };
83EAF76618E8F70400C896A6 /* dbopl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dbopl.c; sourceTree = "<group>"; };
83EAF76718E8F70400C896A6 /* dbopl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbopl.h; sourceTree = "<group>"; };
83F1529219C667000000856F /* barray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = barray.h; sourceTree = "<group>"; };
83F1529319C667000000856F /* barray.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = barray.c; sourceTree = "<group>"; };
83F4D53A18D82105009B2DE6 /* modplay.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = modplay.framework; sourceTree = BUILT_PRODUCTS_DIR; };
83F4D54518D82105009B2DE6 /* modplay-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "modplay-Info.plist"; sourceTree = "<group>"; };
83F4D54718D82105009B2DE6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
@ -78,6 +82,8 @@
83F4D54318D82105009B2DE6 /* modplay */ = {
isa = PBXGroup;
children = (
83F1529219C667000000856F /* barray.h */,
83F1529319C667000000856F /* barray.c */,
83EAF76618E8F70400C896A6 /* dbopl.c */,
83EAF76718E8F70400C896A6 /* dbopl.h */,
838A72E418DEC9A1007C8A7D /* resampler.c */,
@ -107,6 +113,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
83F1529419C667000000856F /* barray.h in Headers */,
838A72E718DEC9A1007C8A7D /* resampler.h in Headers */,
835CBC8218DA95AC0087A03E /* ft2play.h in Headers */,
83EAF76918E8F70400C896A6 /* dbopl.h in Headers */,
@ -177,6 +184,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
83F1529519C667000000856F /* barray.c in Sources */,
838A72E618DEC9A1007C8A7D /* resampler.c in Sources */,
83EAF76818E8F70400C896A6 /* dbopl.c in Sources */,
83F4D57718D821D2009B2DE6 /* st3play.c in Sources */,

View File

@ -0,0 +1,189 @@
#include "barray.h"
#include <string.h>
void * bit_array_create(size_t size)
{
size_t bsize = ((size + 7) >> 3) + sizeof(size_t);
void * ret = calloc(1, bsize);
if (ret) *(size_t *)ret = size;
return ret;
}
void bit_array_destroy(void * array)
{
if (array) free(array);
}
void * bit_array_dup(void * array)
{
if (array)
{
size_t * size = (size_t *) array;
size_t bsize = ((*size + 7) >> 3) + sizeof(*size);
void * ret = malloc(bsize);
if (ret) memcpy(ret, array, bsize);
return ret;
}
return NULL;
}
void bit_array_reset(void * array)
{
if (array)
{
size_t * size = (size_t *) array;
size_t bsize = (*size + 7) >> 3;
memset(size + 1, 0, bsize);
}
}
void bit_array_set(void * array, size_t bit)
{
if (array)
{
size_t * size = (size_t *) array;
if (bit < *size)
{
unsigned char * ptr = (unsigned char *)(size + 1);
ptr[bit >> 3] |= (1U << (bit & 7));
}
}
}
void bit_array_set_range(void * array, size_t bit, size_t count)
{
if (array && count)
{
size_t * size = (size_t *) array;
if (bit < *size)
{
unsigned char * ptr = (unsigned char *)(size + 1);
size_t i;
for (i = bit; i < *size && i < bit + count; ++i)
ptr[i >> 3] |= (1U << (i & 7));
}
}
}
int bit_array_test(void * array, size_t bit)
{
if (array)
{
size_t * size = (size_t *) array;
if (bit < *size)
{
unsigned char * ptr = (unsigned char *)(size + 1);
if (ptr[bit >> 3] & (1U << (bit & 7)))
{
return 1;
}
}
}
return 0;
}
int bit_array_test_range(void * array, size_t bit, size_t count)
{
if (array)
{
size_t * size = (size_t *) array;
if (bit < *size)
{
unsigned char * ptr = (unsigned char *)(size + 1);
if ((bit & 7) && (count > 8))
{
while ((bit < *size) && count && (bit & 7))
{
if (ptr[bit >> 3] & (1U << (bit & 7))) return 1;
bit++;
count--;
}
}
if (!(bit & 7))
{
while (((*size - bit) >= 8) && (count >= 8))
{
if (ptr[bit >> 3]) return 1;
bit += 8;
count -= 8;
}
}
while ((bit < *size) && count)
{
if (ptr[bit >> 3] & (1U << (bit & 7))) return 1;
bit++;
count--;
}
}
}
return 0;
}
void bit_array_clear(void * array, size_t bit)
{
if (array)
{
size_t * size = (size_t *) array;
if (bit < *size)
{
unsigned char * ptr = (unsigned char *)(size + 1);
ptr[bit >> 3] &= ~(1U << (bit & 7));
}
}
}
void bit_array_clear_range(void * array, size_t bit, size_t count)
{
if (array && count)
{
size_t * size = (size_t *) array;
if (bit < *size)
{
unsigned char * ptr = (unsigned char *)(size + 1);
size_t i;
for (i = bit; i < *size && i < bit + count; ++i)
ptr[i >> 3] &= ~(1U << (i & 7));
}
}
}
void bit_array_merge(void * dest, void * source, size_t offset)
{
if (dest && source)
{
size_t * dsize = (size_t *) dest;
size_t * ssize = (size_t *) source;
size_t soffset = 0;
while (offset < *dsize && soffset < *ssize)
{
if (bit_array_test(source, soffset))
{
bit_array_set(dest, offset);
}
soffset++;
offset++;
}
}
}
void bit_array_mask(void * dest, void * source, size_t offset)
{
if (dest && source)
{
size_t * dsize = (size_t *) dest;
size_t * ssize = (size_t *) source;
size_t soffset = 0;
while (offset < *dsize && soffset < *ssize)
{
if (bit_array_test(source, soffset))
{
bit_array_clear(dest, offset);
}
soffset++;
offset++;
}
}
}

View File

@ -0,0 +1,24 @@
#ifndef _B_ARRAY_H_
#define _B_ARRAY_H_
#include <stdlib.h>
void * bit_array_create(size_t size);
void bit_array_destroy(void * array);
void * bit_array_dup(void * array);
void bit_array_reset(void * array);
void bit_array_set(void * array, size_t bit);
void bit_array_set_range(void * array, size_t bit, size_t count);
int bit_array_test(void * array, size_t bit);
int bit_array_test_range(void * array, size_t bit, size_t count);
void bit_array_clear(void * array, size_t bit);
void bit_array_clear_range(void * array, size_t bit, size_t count);
void bit_array_merge(void * array, void * source, size_t offset);
void bit_array_mask(void * array, void * source, size_t offset);
#endif

View File

@ -42,6 +42,8 @@
#include "resampler.h"
#include "barray.h"
#include "ft2play.h"
#if defined(_MSC_VER) && !defined(inline)
@ -425,7 +427,7 @@ typedef struct
uint8_t muted[16];
uint32_t loopCount;
uint8_t playedOrder[8192];
void * playedRows;
} PLAYER;
/* FUNCTION DECLARATIONS */
@ -879,11 +881,9 @@ static void CheckEffects(PLAYER *p, StmTyp *ch)
p->Song.PBreakFlag = 1;
}
}
if (p->Song.PBreakFlag == 1 && p->Song.PBreakPos == 0)
if (p->Song.PBreakFlag == 1)
{
int32_t offset = p->Song.SongPos / 8;
int32_t bit = 1 << (p->Song.SongPos % 8);
p->playedOrder[offset] &= ~bit;
bit_array_clear_range(p->playedRows, p->Song.SongPos * 1024 + ch->PattPos, (p->Song.PattPos & 0x00FF) - ch->PattPos + 1);
}
}
}
@ -2118,7 +2118,11 @@ static void MainPlayer(PLAYER *p) /* periodically called from mixer */
if (p->Song.PattDelTime2)
{
p->Song.PattDelTime2--;
if (p->Song.PattDelTime2) p->Song.PattPos--;
if (p->Song.PattDelTime2)
{
p->Song.PattPos--;
bit_array_clear(p->playedRows, p->Song.SongPos * 1024 + p->Song.PattPos);
}
}
if (p->Song.PBreakFlag)
@ -2140,17 +2144,12 @@ static void MainPlayer(PLAYER *p) /* periodically called from mixer */
p->Song.PattLen = p->PattLens[p->Song.PattNr];
}
if (p->Song.PattPos == 0)
if (bit_array_test(p->playedRows, p->Song.SongPos * 1024 + p->Song.PattPos))
{
int32_t offset = p->Song.SongPos / 8;
int32_t bit = 1 << (p->Song.SongPos % 8);
if (p->playedOrder[offset] & bit)
{
p->loopCount++;
memset(p->playedOrder, 0, sizeof(p->playedOrder));
}
p->playedOrder[offset] |= bit;
p->loopCount++;
bit_array_reset(p->playedRows);
}
bit_array_set(p->playedRows, p->Song.SongPos * 1024 + p->Song.PattPos);
}
}
else
@ -3855,6 +3854,8 @@ void * ft2play_Alloc(uint32_t _samplingFrequency, int8_t interpolation, int8_t r
/* generate FT2's pan table [round(65536*sqrt(n/256)) for n = 0...256] */
for (i = 0; i < 257; ++i)
p->PanningTab[i] = sqrtf((float)(i) / 256.0f);
p->playedRows = NULL;
return p;
@ -3871,6 +3872,8 @@ void ft2play_Free(void *_p)
if (p->Playing)
{
if (p->playedRows) bit_array_destroy(p->playedRows); p->playedRows = NULL;
if (p->masterBufferL) free(p->masterBufferL); p->masterBufferL = NULL;
if (p->masterBufferR) free(p->masterBufferR); p->masterBufferR = NULL;
}
@ -3915,8 +3918,10 @@ void ft2play_PlaySong(void *_p, int32_t startOrder)
p->Song.startOrder = (int16_t)startOrder;
p->loopCount = 0;
memset(p->playedOrder, 0, sizeof(p->playedOrder));
p->playedOrder[startOrder / 8] = 1 << (startOrder % 8);
if (p->playedRows) bit_array_destroy(p->playedRows);
p->playedRows = bit_array_create(1024 * (p->Song.Len ?: 1));
bit_array_set(p->playedRows, startOrder * 1024);
}
static int mopen_is_big_endian;