shithub: dumb

Download patch

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);