示例#1
0
/* Expand a spline segment into a buffer */
static int expandSpline(AS3_Val *modPoint, float *buffer, int frames) 
{
	
	double y0Arg, y1Arg, y2Arg, y3Arg;
	float y0, y1, y2, y3;
	float p, incr;
	int count;
	AS3_ObjectValue(*modPoint, "y0:DoubleType, y1:DoubleType, y2:DoubleType, y3:DoubleType", &y0Arg, &y1Arg, &y2Arg, &y3Arg);
	y0 = (float) y0Arg;
	y1 = (float) y1Arg;
	y2 = (float) y2Arg;
	y3 = (float) y3Arg;
	incr = 1 / (float) frames;
	count = frames;
	p = 0;
	// Optimize continuous, linear, and cubic modes
	if (y0 == 0 && y1 == 0 && y2 == 0 && y3 == 0 ) {
		// All values are zero
		memset(buffer, 0, frames * 4);
	} else if (y0 == y1 && y1 == y2 && y2 == y3) {
		// All values are the same
		while (count--) {
			*buffer++ = y1;
		}
	} else if (y0 == y1 && y2 == y3) {
		// Linear interpolation
		while (count--) {
			*buffer++ = interpolate(y1, y2, p);
			p += incr;
		}
	} else {
		// This is a full spline segment
		// Loop over the whole segment and calc instantaneous spline values with cubic interpolation
		while (count--) {
			*buffer++ = cubicInterpolate(y0, y1, y2, y3, p);
			p += incr;
		}
	}
	return 0;
} 
示例#2
0
// Go check a Flash event queue for events SDL should be aware of!
void FLASH_PumpEvents(_THIS)
{
	if (!FLASH_EMPTY_PARAMS)
		FLASH_EMPTY_PARAMS = AS3_Array("");
	
	// Event Vars
	AS3_Val mouseEvent, mouseEvents, mousePosition, keyboardEvent, keyboardEvents;
	int buttonState, rawKeyboardEvent, scanCode, keyState;
	SDL_keysym keysym;
	
	mousePosition = AS3_CallS( "pumpMousePosition", FLASH_EVENT_MANAGER_OBJECT, FLASH_EMPTY_PARAMS );
	mouseEvents = AS3_CallS( "pumpMouseEvents", FLASH_EVENT_MANAGER_OBJECT, FLASH_EMPTY_PARAMS );
	keyboardEvents = AS3_CallS( "pumpKeyEvents", FLASH_EVENT_MANAGER_OBJECT, FLASH_EMPTY_PARAMS );
	
	// Mouse Position
	if (mousePosition) {
		AS3_ObjectValue( mousePosition, "x:IntType, y:IntType", &FLASH_mouseX, &FLASH_mouseY );	
		SDL_PrivateMouseMotion( 0, 0, FLASH_mouseX, FLASH_mouseY );
	}
	
	// Mouse Click Events
	while( AS3_IntValue(AS3_GetS(mouseEvents, "size")) > 0 ) {
		mouseEvent = AS3_CallS( "dequeue", mouseEvents, FLASH_EMPTY_PARAMS );
		buttonState = AS3_IntValue( mouseEvent )? SDL_PRESSED: SDL_RELEASED;
		SDL_PrivateMouseButton(buttonState, SDL_BUTTON_LEFT, FLASH_mouseX, FLASH_mouseY);
	}
	
	// Keyboard Events
	while( AS3_IntValue(AS3_GetS(keyboardEvents, "size")) > 0 ) {
		keyboardEvent = AS3_CallS( "dequeue", keyboardEvents, FLASH_EMPTY_PARAMS );
		rawKeyboardEvent = AS3_IntValue( keyboardEvent );
		scanCode = rawKeyboardEvent & 0xFF;		// Packed event format: 9th bit for press/release, lower 8 bits for scan code
		keyState = rawKeyboardEvent >> 8;
		SDL_PrivateKeyboard(keyState, TranslateKey(scanCode, &keysym));
	}
}
示例#3
0
static AS3_Val biquad(void *self, AS3_Val args)
{
	int bufferPosition;  int channels; int frames; int count; 
	float *buffer; 
	int stateBufferPosition;
	float *stateBuffer;
	
	AS3_Val coeffs; // coefficients object
	double a0d, a1d, a2d, b0d, b1d, b2d; // doubles from object
	float a0, a1, a2, b0, b1, b2; // filter coefficients
	float lx, ly, lx1, lx2, ly1, ly2; // left delay line 
	float rx, ry, rx1, rx2, ry1, ry2; // right delay line 
	
	// Extract args
	AS3_ArrayValue(args, "IntType, IntType, IntType, IntType, AS3ValType", 
		&bufferPosition, &stateBufferPosition, &channels, &frames, &coeffs);
	buffer = (float *) bufferPosition;
	stateBuffer = (float *) stateBufferPosition;	
		
	// Extract filter coefficients from object	
	AS3_ObjectValue(coeffs, "a0:DoubleType, a1:DoubleType, a2:DoubleType, b0:DoubleType, b1:DoubleType, b2:DoubleType",
		&a0d, &a1d, &a2d, &b0d, &b1d, &b2d);
	// Cast to floats
	a0 = (float) a0d; a1 = (float) a1d; a2 = (float) a2d; 	
	b0 = (float) b0d; b1 = (float) b1d; b2 = (float) b2d; 	

	// Make sure we recieved all the correct coefficients 
	// sprintf(trace, "Biquad a0=%f a1=%f a2=%f b0=%f b1=%f b2=%f", a0, a1, a2, b0, b1, b2);
	// sztrace(trace);
		
	count = frames;

	if (channels == 1) {
		lx1 = *stateBuffer;
		lx2 = *(stateBuffer+1);
		ly1 = *(stateBuffer+2);
		ly2 = *(stateBuffer+3);
		while (count--) {
			lx = *buffer + 1e-15 - 1e-15; // input with denormals zapped
            ly = lx*b0 + lx1*b1 + lx2*b2 - ly1*a1 - ly2*a2;
			lx2 = lx1;
			lx1 = lx;
			ly2 = ly1;
			ly1 = ly;
            *buffer++ = ly; // output
		}
		*stateBuffer = lx1;
		*(stateBuffer+1) = lx2;
		*(stateBuffer+2) = ly1;
		*(stateBuffer+3) = ly2;
	} else if (channels == 2) {
		lx1 = *stateBuffer;
		rx1 = *(stateBuffer+1);
		lx2 = *(stateBuffer+2);
		rx2 = *(stateBuffer+3);
		ly1 = *(stateBuffer+4);
		ry1 = *(stateBuffer+5);
		ly2 = *(stateBuffer+6);
		ry2 = *(stateBuffer+7);
		while (count--) {
			lx = *buffer + 1e-15 - 1e-15; // left input
            ly = lx*b0 + lx1*b1 + lx2*b2 - ly1*a1 - ly2*a2;
			lx2 = lx1;
			lx1 = lx;
			ly2 = ly1;
			ly1 = ly;
            *buffer++ = ly; // left output
			rx = *buffer + 1e-15 - 1e-15; // right input
            ry = rx*b0 + rx1*b1 + rx2*b2 - ry1*a1 - ry2*a2;
			rx2 = rx1;
			rx1 = rx;
			ry2 = ry1;
			ry1 = ry;
            *buffer++ = ry; // right output
		}
		*stateBuffer = lx1;
		*(stateBuffer+1) = rx1;
		*(stateBuffer+2) = lx2;
		*(stateBuffer+3) = rx2;
		*(stateBuffer+4) = ly1;
		*(stateBuffer+5) = ry1;
		*(stateBuffer+6) = ly2;
		*(stateBuffer+7) = ry2;
	}

	return 0;
}
示例#4
0
static AS3_Val delay(void *self, AS3_Val args)
{
	int bufferPosition; int channels; int frames; int count; 
	float *buffer; 
	int ringBufferPosition;
	float *ringBuffer;
	AS3_Val settings;
	int length;
	double feedbackArg; float feedback;
	double dryMixArg; float dryMix;
	double wetMixArg; float wetMix;
	int offset = 0;
	float echo;
	float *echoPointer;
	
	// Extract	args
	AS3_ArrayValue(args, "IntType, IntType, IntType, IntType, AS3ValType", 
	    &bufferPosition, &ringBufferPosition, &channels, &frames,  &settings);
	AS3_ObjectValue(settings, "length:IntType, dryMix:DoubleType, wetMix:DoubleType, feedback:DoubleType",
		&length, &dryMixArg, &wetMixArg, &feedbackArg);
	// Cast arguments to the needed types
	buffer = (float *) bufferPosition;
	ringBuffer = (float *) ringBufferPosition;
	dryMix = (float) dryMixArg;
	wetMix = (float) wetMixArg;
	feedback = (float) feedbackArg;
	
	// Show params
	// sprintf(trace, "Echo length=%d, dry=%f, wet=%f, fb=%f", length, dryMix, wetMix, feedback); 
	// sztrace(trace);
	
	count = frames * channels;
	while (count--) {
		if (offset > length) { 
			offset = 0; 
		}
		echoPointer = ringBuffer + offset;
		echo = *echoPointer;
		*echoPointer = *buffer + echo*feedback;
		*buffer = *buffer * dryMix + echo * wetMix + 1e-15 - 1e-15;
		buffer++; offset++;
	}		
	
	
	// Shift the memory so that the echo pointer offset is the start of the buffer
	
	int ringSize = length * channels * sizeof(float);
	int firstChunkSize = offset * channels * sizeof(float);
	int secondChunkSize = ringSize - firstChunkSize;
	float *temp = (float *) malloc(ringSize);
	
	// copy offset-end -> start of temp buffer	
	memcpy(temp, ringBuffer + offset, secondChunkSize);

	// copy start-offset -> second half of temp buffer
	memcpy(temp + offset, ringBuffer, firstChunkSize);
	
	// copy temp buffer back to ringbuffer
	memcpy(ringBuffer, temp, ringSize); 
	free(temp);
	
	return 0;
	
}
示例#5
0
/**
 * Scan in a wavetable. Wavetable should be at least one longer than the table size.
 */
static AS3_Val wavetableIn(void *self, AS3_Val args)
{
	AS3_Val settings;
	int bufferPosition; int channels; int frames;
	float *buffer; 
	int sourceBufferPosition;
	float *sourceBuffer;
	double phaseArg; float phase;
	double phaseAddArg; float phaseAdd;
	double phaseResetArg; float phaseReset;
	int tableSize;
	int count; 
	int intPhase;
	float *wavetablePosition;
	float *scratch;
	double y1Arg, y2Arg;
	float y1, y2;
	float fractional, fractionalIncrement, instantBend;
	
	
	
	AS3_ArrayValue(args, "IntType, IntType, IntType, IntType, AS3ValType", &bufferPosition, &sourceBufferPosition, &channels, &frames, &settings);
	AS3_ObjectValue(settings, "tableSize:IntType, phase:DoubleType, phaseAdd:DoubleType, phaseReset:DoubleType, y1:DoubleType, y2:DoubleType",
		&tableSize, &phaseArg, &phaseAddArg, &phaseResetArg, &y1Arg, &y2Arg);

	buffer = (float *) bufferPosition;
	sourceBuffer = (float *) sourceBufferPosition; 
	phaseAdd = (float) phaseAddArg * tableSize; // num source frames to add per output frames
	phase = (float) phaseArg * tableSize; // translate into a frame count into the table
	phaseReset = (float) phaseResetArg * tableSize;
	y1 = (float) y1Arg;
	y2 = (float) y2Arg;
	
	// Expand the pitch modulation into scratch
	// expandLine(scratch1, y1, y2, frames); // draws spline segment into scratch1
	// scratch = (float *) scratch1;	
		
	// Make sure we got everything right
	//sprintf(trace, "Wavetable size=%d phase=%f phaseAdd=%f y1=%f y2=%f", tableSize, phase, phaseAdd, y1, y2);
	//sztrace(trace);	
				
	count=frames;
	fractional = 0.0;
	fractionalIncrement = 1 / (float) frames;
	
	if (channels == 1) {
		while (count--) {
			while (phase >= tableSize) {
				if (phaseReset == -1) {
					// no looping!
					return 0; 
				} else {
					// wrap phase to the loop point
					phase -= tableSize; 
					phase += phaseReset;
				}
			}
			intPhase = (int) phase; // int phase
			wavetablePosition = sourceBuffer + intPhase;
			*buffer++ = interpolate(*wavetablePosition, *(wavetablePosition+1), phase - intPhase);
			// Increment phase by adjusting phaseAdd for instantaneous pitch bend 
			instantBend = interpolate(y1, y2, fractional);
			fractional += fractionalIncrement;
			phase +=  phaseAdd * shiftToFreq(instantBend); 
		}		
	} else if (channels == 2 ) {
		while (count--) {
			while (phase >= tableSize) {
				if (phaseReset == -1) {
					// no looping!
					return 0; 
				} else {
					// wrap phase to the loop point
					phase -= tableSize; 
					phase += phaseReset;
				}
			}
			intPhase = ((int)(phase*0.5))*2; // int phase, round to even frames, for each stereo frame pair
			wavetablePosition = sourceBuffer + intPhase;
			*buffer++ = interpolate(*wavetablePosition, *(wavetablePosition+2), phase - intPhase);
			*buffer++ = interpolate(*(wavetablePosition+1), *(wavetablePosition+3), phase - intPhase);
			// Increment phase by adjusting phaseAdd for instantaneous pitch bend 
			instantBend = interpolate(y1, y2, fractional);
			fractional += fractionalIncrement;
			phase +=  phaseAdd * shiftToFreq(instantBend);
		}
	}
	
	// Scale back down to a factor, and write the final phase value back to AS3
	phase /= tableSize;
	AS3_Set(settings, AS3_String("phase"), AS3_Number(phase));
	
	return 0;
}