ref: 022c14c3cf3d0cd0045b60f5108b6fdb5f4c8b5b
parent: 24244696518e81dccac26d13e0acfdaeec56b79e
author: Chris Moeller <kode54@gmail.com>
date: Wed Apr 8 22:16:35 EDT 2015
Various fixes for Android
--- a/dumb/include/internal/barray.h
+++ b/dumb/include/internal/barray.h
@@ -4,6 +4,8 @@
#include <stdlib.h>
#ifdef BARRAY_DECORATE
+#undef PASTE
+#undef EVALUATE
#define PASTE(a,b) a ## b
#define EVALUATE(a,b) PASTE(a,b)
#define bit_array_create EVALUATE(BARRAY_DECORATE,_bit_array_create)
--- a/dumb/include/internal/resampler.h
+++ b/dumb/include/internal/resampler.h
@@ -3,6 +3,8 @@
// Ugglay
#ifdef RESAMPLER_DECORATE
+#undef PASTE
+#undef EVALUATE
#define PASTE(a,b) a ## b
#define EVALUATE(a,b) PASTE(a,b)
#define resampler_init EVALUATE(RESAMPLER_DECORATE,_resampler_init)
--- a/dumb/src/helpers/resampler.c
+++ b/dumb/src/helpers/resampler.c
@@ -9,9 +9,11 @@
#ifdef __APPLE__
#include <TargetConditionals.h>
#if TARGET_CPU_ARM || TARGET_CPU_ARM64
-#include <arm_neon.h>
#define RESAMPLER_NEON
#endif
+#endif
+#ifdef RESAMPLER_NEON
+#include <arm_neon.h>
#endif
#ifdef _MSC_VER
--- a/dumb/src/it/itread.c
+++ b/dumb/src/it/itread.c
@@ -53,13 +53,13 @@
size = dumbfile_igetw(f);
if (size < 0)
- return size;
+ return (int)size;
crap->sourcebuf = malloc(size);
if (!crap->sourcebuf)
return -1;
- c = dumbfile_getnc((char *)crap->sourcebuf, size, f);
+ c = (int)dumbfile_getnc((char *)crap->sourcebuf, size, f);
if (c < size) {
free(crap->sourcebuf);
crap->sourcebuf = NULL;
@@ -114,7 +114,7 @@
int blocklen, blockpos;
byte bitwidth;
word val;
- char d1, d2;
+ signed char d1, d2;
readblock_crap crap;
memset(&crap, 0, sizeof(crap));
@@ -166,7 +166,7 @@
//Expand the value to signed byte:
{
- char v; //The sample value:
+ signed char v; //The sample value:
if (bitwidth < 8) {
byte shift = 8 - bitwidth;
v = (val << shift);
@@ -173,7 +173,7 @@
v >>= shift;
}
else
- v = (char)val;
+ v = (signed char)val;
//And integrate the sample value
//(It always has to end with integration doesn't it ? ;-)
@@ -202,7 +202,7 @@
int blocklen, blockpos;
byte bitwidth;
long val;
- short d1, d2;
+ signed short d1, d2;
readblock_crap crap;
memset(&crap, 0, sizeof(crap));
@@ -428,7 +428,8 @@
static int it_read_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f, int maxlen)
{
- int n, len;
+ int n;
+ long len;
/*if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE)
return -1;*/
@@ -435,6 +436,7 @@
// XXX
if (maxlen) len = dumbfile_pos(f);
+ else len = 0;
dumbfile_skip(f, 4);
@@ -660,17 +662,17 @@
if (sample->flags & IT_SAMPLE_STEREO) {
if (sample->flags & IT_SAMPLE_16BIT) {
- decompress16(f, (short *) sample->data, datasize >> 1, convert & 4, 1);
- decompress16(f, (short *) sample->data + 1, datasize >> 1, convert & 4, 1);
+ decompress16(f, (short *) sample->data, (int)(datasize >> 1), convert & 4, 1);
+ decompress16(f, (short *) sample->data + 1, (int)(datasize >> 1), convert & 4, 1);
} else {
- decompress8(f, (signed char *) sample->data, datasize >> 1, convert & 4, 1);
- decompress8(f, (signed char *) sample->data + 1, datasize >> 1, convert & 4, 1);
+ decompress8(f, (signed char *) sample->data, (int)(datasize >> 1), convert & 4, 1);
+ decompress8(f, (signed char *) sample->data + 1, (int)(datasize >> 1), convert & 4, 1);
}
} else {
if (sample->flags & IT_SAMPLE_16BIT)
- decompress16(f, (short *) sample->data, datasize, convert & 4, 0);
+ decompress16(f, (short *) sample->data, (int)datasize, convert & 4, 0);
else
- decompress8(f, (signed char *) sample->data, datasize, convert & 4, 0);
+ decompress8(f, (signed char *) sample->data, (int)datasize, convert & 4, 0);
}
} else if (sample->flags & IT_SAMPLE_16BIT) {
if (sample->flags & IT_SAMPLE_STEREO) {
@@ -923,8 +925,8 @@
static int it_component_compare(const void *e1, const void *e2)
{
- return ((const IT_COMPONENT *)e1)->offset -
- ((const IT_COMPONENT *)e2)->offset;
+ return (int)(((const IT_COMPONENT *)e1)->offset -
+ ((const IT_COMPONENT *)e2)->offset);
}
@@ -994,7 +996,7 @@
dumbfile_skip(f, 1);
message_length = dumbfile_igetw(f);
- message_offset = dumbfile_igetl(f);
+ message_offset = (int)dumbfile_igetl(f);
/* Skip Reserved. */
dumbfile_skip(f, 4);
@@ -1235,7 +1237,7 @@
case IT_COMPONENT_SONG_MESSAGE:
if ( n < n_components ) {
- message_length = min( message_length, component[n+1].offset - component[n].offset );
+ message_length = min( message_length, (int)(component[n+1].offset - component[n].offset) );
}
sigdata->song_message = malloc(message_length + 1);
if (sigdata->song_message) {
@@ -1253,7 +1255,7 @@
if (cmwt < 0x200)
m = it_read_old_instrument(&sigdata->instrument[component[n].n], f);
else
- m = it_read_instrument(&sigdata->instrument[component[n].n], f, (n + 1 < n_components) ? (component[n+1].offset - component[n].offset) : 0);
+ m = it_read_instrument(&sigdata->instrument[component[n].n], f, (n + 1 < n_components) ? (int)(component[n+1].offset - component[n].offset) : 0);
if (m) {
free(buffer);
@@ -1340,7 +1342,7 @@
if ( !dumbfile_error( f ) && n < 10 )
{
- unsigned int mptx_id = dumbfile_igetl( f );
+ unsigned int mptx_id = (unsigned int)dumbfile_igetl( f );
while ( !dumbfile_error( f ) && mptx_id != DUMB_ID('M','P','T','S') )
{
unsigned int size = dumbfile_igetw( f );
@@ -1353,10 +1355,10 @@
break;
}
- mptx_id = dumbfile_igetl( f );
+ mptx_id = (unsigned int)dumbfile_igetl( f );
}
- mptx_id = dumbfile_igetl( f );
+ mptx_id = (unsigned int)dumbfile_igetl( f );
while ( !dumbfile_error(f) && dumbfile_pos(f) < dumbfile_get_size(f) )
{
unsigned int size = dumbfile_igetw( f );
@@ -1368,7 +1370,7 @@
if ( size == 2 )
sigdata->tempo = dumbfile_igetw( f );
else if ( size == 4 )
- sigdata->tempo = dumbfile_igetl( f );
+ sigdata->tempo = (int)dumbfile_igetl( f );
break;
default:
@@ -1375,7 +1377,7 @@
dumbfile_skip(f, size);
break;
}
- mptx_id = dumbfile_igetl( f );
+ mptx_id = (unsigned int)dumbfile_igetl( f );
}
}
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -28,6 +28,16 @@
#include "internal/resampler.h"
+// Keep this disabled, as it's actually slower than the original C/integer version
+//
+//#ifdef __APPLE__
+//#include <TargetConditionals.h>
+//#if TARGET_CPU_ARM || TARGET_CPU_ARM64
+//#include <arm_neon.h>
+//#define FILTER_NEON
+//#endif
+//#endif
+
// #define BIT_ARRAY_BULLSHIT
static IT_PLAYING *new_playing()
@@ -742,6 +752,91 @@
}
#endif
+#ifdef FILTER_NEON
+static void it_filter_neon(DUMB_CLICK_REMOVER *cr, IT_FILTER_STATE *state, sample_t *dst, long pos, sample_t *src, long size, int step, int sampfreq, int cutoff, int resonance)
+{
+ float32x4_t data, impulse;
+ float32x4_t temp1;
+ float32x2_t temp2;
+ float32_t temp3;
+
+ sample_t currsample = state->currsample;
+ sample_t prevsample = state->prevsample;
+
+ float imp[4];
+
+ //profiler( filter_sse ); On ClawHammer Athlon64 3200+, ~12000 cycles, ~500 for that x87 setup code (as opposed to ~25500 for the original integer code)
+
+ long datasize;
+
+ {
+ float inv_angle = (float)(sampfreq * pow(0.5, 0.25 + cutoff*(1.0/(24<<IT_ENVELOPE_SHIFT))) * (1.0/(2*3.14159265358979323846*110.0)));
+ float loss = (float)exp(resonance*(-LOG10*1.2/128.0));
+ float d, e;
+#if 0
+ loss *= 2; // This is the mistake most players seem to make!
+#endif
+
+#if 1
+ d = (1.0f - loss) / inv_angle;
+ if (d > 2.0f) d = 2.0f;
+ d = (loss - d) * inv_angle;
+ e = inv_angle * inv_angle;
+ imp[0] = 1.0f / (1.0f + d + e);
+ imp[2] = -e * imp[0];
+ imp[1] = 1.0f - imp[0] - imp[2];
+#else
+ imp[0] = 1.0f / (inv_angle*inv_angle + inv_angle*loss + loss);
+ imp[2] = -(inv_angle*inv_angle) * imp[0];
+ imp[1] = 1.0f - imp[0] - imp[2];
+#endif
+ imp[3] = 0.0f;
+ }
+
+ dst += pos * step;
+ datasize = size * step;
+
+ {
+ int ai, bi, ci, i;
+
+ if (cr) {
+ sample_t startstep;
+ ai = (int)(imp[0] * (1 << (16+SCALEB)));
+ bi = (int)(imp[1] * (1 << (16+SCALEB)));
+ ci = (int)(imp[2] * (1 << (16+SCALEB)));
+ startstep = MULSCA(src[0], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);
+ dumb_record_click(cr, pos, startstep);
+ }
+
+ data = vdupq_n_f32(0.0f);
+ data = vsetq_lane_f32( currsample, data, 1 );
+ data = vsetq_lane_f32( prevsample, data, 2 );
+ impulse = vld1q_f32( (const float32_t *) &imp );
+
+ for (i = 0; i < datasize; i += step) {
+ data = vsetq_lane_f32( src [i], data, 0 );
+ temp1 = vmulq_f32(data, impulse);
+ temp2 = vadd_f32(vget_high_f32(temp1), vget_low_f32(temp1));
+ temp3 = vget_lane_f32(vpadd_f32(temp2, temp2), 0);
+ data = vextq_f32(data, data, 3);
+ data = vsetq_lane_f32(temp3, data, 1);
+ dst [i] += temp3;
+ }
+
+ currsample = temp3;
+ prevsample = vgetq_lane_f32(data, 2);
+
+ if (cr) {
+ sample_t endstep = MULSCA(src[datasize], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);
+ dumb_record_click(cr, pos + size, -endstep);
+ }
+ }
+
+ state->currsample = currsample;
+ state->prevsample = prevsample;
+}
+#endif
+
#undef LOG10
#ifdef _USE_SSE
@@ -821,7 +916,11 @@
if ( _dumb_it_use_sse ) it_filter_sse( cr, state, dst, pos, src, size, step, sampfreq, cutoff, resonance );
else
#endif
+#ifdef FILTER_NEON
+ it_filter_neon( cr, state, dst, pos, src, size, step, sampfreq, cutoff, resonance );
+#else
it_filter_int( cr, state, dst, pos, src, size, step, sampfreq, cutoff, resonance );
+#endif
}
@@ -2076,7 +2175,7 @@
static void it_send_midi(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *channel, unsigned char midi_byte)
{
if (sigrenderer->callbacks->midi)
- if ((*sigrenderer->callbacks->midi)(sigrenderer->callbacks->midi_data, channel - sigrenderer->channel, midi_byte))
+ if ((*sigrenderer->callbacks->midi)(sigrenderer->callbacks->midi_data, (int)(channel - sigrenderer->channel), midi_byte))
return;
switch (channel->midi_state) {
@@ -2555,11 +2654,11 @@
IT_SAMPLE *sample = playing->sample;
int end;
if ((sample->flags & IT_SAMPLE_SUS_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF))
- end = sample->sus_loop_end;
+ end = (int)sample->sus_loop_end;
else if (sample->flags & IT_SAMPLE_LOOP)
- end = sample->loop_end;
+ end = (int)sample->loop_end;
else {
- end = sample->length;
+ end = (int)sample->length;
if ( sigdata->flags & IT_WAS_PROCESSED && end > 64 ) // XXX bah damn LPC and edge case modules
end -= 64;
}
@@ -3992,7 +4091,7 @@
playing->sample_vibrato_time += playing->sample->vibrato_speed;
}
-#if defined(_MSC_VER) && _MSC_VER < 1800
+#if (defined(_MSC_VER) && _MSC_VER < 1800) || defined(__ANDROID__)
static float log2(float x) {return (float)log(x)/(float)log(2.0f);}
#endif
@@ -4006,6 +4105,7 @@
}
// Period table for Protracker octaves 0-5:
+#if 0
static const unsigned short ProTrackerPeriodTable[6*12] =
{
1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907,
@@ -4036,6 +4136,7 @@
1736,1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,
1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914
};
+#endif
static void process_all_playing(DUMB_IT_SIGRENDERER *sigrenderer)
{
@@ -4137,7 +4238,7 @@
}
if (playing->channel->glissando && playing->channel->toneporta && playing->channel->destnote < 120) {
- playing->delta = (float)pow(DUMB_SEMITONE_BASE, delta_to_note(playing->delta, playing->sample->C5_speed) - 60)
+ playing->delta = (float)pow(DUMB_SEMITONE_BASE, delta_to_note(playing->delta, (int)playing->sample->C5_speed) - 60)
* playing->sample->C5_speed * (1.f / 65536.f);
}
@@ -5613,9 +5714,9 @@
#ifdef BIT_ARRAY_BULLSHIT
static long it_sigrenderer_get_position(sigrenderer_t *vsigrenderer)
{
- DUMB_IT_SIGRENDERER *sigrenderer = vsigrenderer;
+ DUMB_IT_SIGRENDERER *sigrenderer = (DUMB_IT_SIGRENDERER *) vsigrenderer;
- return sigrenderer->time_played >> 16;
+ return (long)(sigrenderer->time_played >> 16);
}
#endif
@@ -5671,7 +5772,7 @@
if (playing->flags & IT_PLAYING_DEAD) { state->sample = 0; return; }
- state->channel = playing->channel - sr->channel;
+ state->channel = (int)(playing->channel - sr->channel);
state->sample = playing->sampnum;
state->volume = calculate_volume(sr, playing, 1.0f);
--- a/dumb/src/it/readamf.c
+++ b/dumb/src/it/readamf.c
@@ -210,7 +210,7 @@
dumbfile_getnc( (char *) sample->filename, 13, f );
sample->filename[13] = 0;
- *offset = dumbfile_igetl( f );
+ *offset = (int)dumbfile_igetl( f );
sample->length = dumbfile_igetl( f );
sample->C5_speed = dumbfile_igetw( f );
sample->default_volume = dumbfile_getc( f );
@@ -259,14 +259,14 @@
return -1;
if ( sample->length )
- read_length = dumbfile_getnc( sample->data, sample->length, f );
+ read_length = (int)dumbfile_getnc( sample->data, sample->length, f );
for ( i = 0; i < read_length; i++ ) {
- ( ( char * ) sample->data )[ i ] ^= 0x80;
+ ( ( signed char * ) sample->data )[ i ] ^= 0x80;
}
for ( i = read_length; i < sample->length; i++ ) {
- ( ( char * ) sample->data )[ i ] = 0;
+ ( ( signed char * ) sample->data )[ i ] = 0;
}
return 0; /* Sometimes the last sample is truncated :( */
--- a/dumb/src/it/readoldpsm.c
+++ b/dumb/src/it/readoldpsm.c
@@ -169,8 +169,8 @@
} else {
if (flags & 4) {
for (o = 0; o < s->length; o++) {
- delta += (short)(sdata[o * 2] | (sdata[(o * 2) + 1] << 8));
- ((short *)s->data)[o] = delta;
+ delta += (signed short)(sdata[o * 2] | (sdata[(o * 2) + 1] << 8));
+ ((signed short *)s->data)[o] = delta;
}
} else {
for (o = 0; o < s->length; o++) {
@@ -464,7 +464,7 @@
}
}
- p->n_entries = entry - p->entry;
+ p->n_entries = (int)(entry - p->entry);
offset += psize;
}
@@ -493,8 +493,8 @@
static int psm_component_compare(const void *e1, const void *e2)
{
- return ((const PSM_COMPONENT *)e1)->offset -
- ((const PSM_COMPONENT *)e2)->offset;
+ return (int)(((const PSM_COMPONENT *)e1)->offset -
+ ((const PSM_COMPONENT *)e2)->offset);
}
static DUMB_IT_SIGDATA *it_old_psm_load_sigdata(DUMBFILE *f)
@@ -590,7 +590,7 @@
if (!n_components) goto error_fc;
- total_pattern_size = dumbfile_igetl(f);
+ total_pattern_size = (int)dumbfile_igetl(f);
if (!total_pattern_size) goto error_fc;
qsort(component, n_components, sizeof(PSM_COMPONENT), &psm_component_compare);