Example #1
0
/**
 * Initiate the playing of a sound resource.
 * @param resnum Resource number
 */
void SoundGen2GS::play(int resnum) {
	AgiSoundEmuType type;

	_playingSound = resnum;

	type = (AgiSoundEmuType)_vm->_game.sounds[resnum]->type();
	assert (type == AGI_SOUND_SAMPLE || type == AGI_SOUND_MIDI);

	if (_vm->_soundemu != SOUND_EMU_APPLE2GS) {
		warning("Trying to play sample or MIDI resource but not using Apple IIGS sound emulation mode");
		return;
	}

	haltGenerators();

	switch (type) {
	case AGI_SOUND_SAMPLE: {
		IIgsSample *sampleRes = (IIgsSample *) _vm->_game.sounds[_playingSound];
		const IIgsSampleHeader &header = sampleRes->getHeader();
		_channels[kSfxMidiChannel].setInstrument(&header.instrument);
		_channels[kSfxMidiChannel].setVolume(header.volume);
		midiNoteOn(kSfxMidiChannel, header.pitch, 127);
		break;
	}
	case AGI_SOUND_MIDI:
		((IIgsMidi *) _vm->_game.sounds[_playingSound])->rewind();
		_ticks = 0;
		break;
	default:
		break;
	}
}
Example #2
0
//*****************************************************************************
// This example demonstrates MIDI functionality and control methods
//*****************************************************************************
int main(void){

    // Set the clocking to run directly from the crystal.
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    // Enable the peripherals used by this VS1053.
	SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);	// VS1053 Serial
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);	// VS1053 Serial
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);	// VS1053 Reset + EMG Input
	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);		// EMG Input 1

	// Enable PC Console
	InitSerial();

    // Enable processor interrupts.
    IntMasterEnable();

	// Set GPIO B0 and B1 as UART pins for VS1053 Control
    GPIOPinConfigure(GPIO_PB0_U1RX);
	GPIOPinConfigure(GPIO_PB1_U1TX);
	GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

	// Set GPIO E4 as Hardware Reset pin and E5 as ADC Input
	GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_4);
	GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_5);

    // Configure the UART1 as according to VS1053 Datasheet with baudrate of 31250
	UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 31250, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    // Setup ADC Sampling Sequences 3, configure step 0.
    // Note: Sequence 1 and 2 has 4 step, which would be great for 3-channel sampling
    ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
    ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH8 | ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceEnable(ADC0_BASE, 3);
    ADCIntClear(ADC0_BASE, 3);

    // Example Started
	UARTprintf("VS1053 Test\n");

	// Reset the VS1053
	VS1053_Reset();

	// Setup the MIDI Channel 0
	midiSetChannelBank(0, VS1053_BANK_MELODY);
	midiSetInstrument(0, VS1053_GM1_OCARINA);
	midiSetChannelVolume(0, 127);
	midiNoteOn(0, 70, 127);
	Delay(1000);

	// Setup the MIDI Channel 1
	midiSetChannelBank(1, VS1053_BANK_MELODY);
	midiSetInstrument(1, VS1053_GM1_OCARINA);
	midiSetChannelVolume(1, 0);
	midiNoteOn(1, 60, 127);

	// Setup variables for ADC
	uint32_t ADC_Output[1];
	uint8_t volume;

    // Infinite Loop of execution
    while(1)
    {

		// ADC Sampling Procedures
		ADCProcessorTrigger(ADC0_BASE, 3);
		while(!ADCIntStatus(ADC0_BASE, 3, false)) {}
		ADCIntClear(ADC0_BASE, 3);
		ADCSequenceDataGet(ADC0_BASE, 3, ADC_Output);
		UARTprintf("AIN8 = %4d\n", ADC_Output[0]);

		// Play Sound as according to voltage level
		volume = inputMapping(ADC_Output[0], 3000, 4000, 50, 127);
		midiSetChannelVolume(0, volume);
		UARTprintf("Volume Level = %4d\n", volume);

		// Delay
		Delay(100);

    }
}
Example #3
0
void SoundGen2GS::playMidiSound() {
	if (_disabledMidi)
		return;

	const uint8 *p;
	uint8 parm1, parm2;
	static uint8 cmd, ch;

	if (_playingSound == -1 || _vm->_game.sounds[_playingSound] == NULL) {
		warning("Error playing Apple IIGS MIDI sound resource");
		_playing = false;

		return;
	}

	IIgsMidi *midiObj = (IIgsMidi *) _vm->_game.sounds[_playingSound];

	_playing = true;
	p = midiObj->getPtr();

	midiObj->_soundBufTicks++;

	while (true) {
		uint8 readByte = *p;

		// Check for end of MIDI sequence marker (Can also be here before delta-time)
		if (readByte == MIDI_BYTE_STOP_SEQUENCE) {
			debugC(3, kDebugLevelSound, "End of MIDI sequence (Before reading delta-time)");
			_playing = false;

			midiObj->rewind();

			return;
		} else if (readByte == MIDI_BYTE_TIMER_SYNC) {
			debugC(3, kDebugLevelSound, "Timer sync");
			p++; // Jump over the timer sync byte as it's not needed

			continue;
		}

		uint8 deltaTime = readByte;
		if (midiObj->_midiTicks + deltaTime > midiObj->_soundBufTicks) {
			break;
		}
		midiObj->_midiTicks += deltaTime;
		p++; // Jump over the delta-time byte as it was already taken care of

		// Check for end of MIDI sequence marker (This time it after reading delta-time)
		if (*p == MIDI_BYTE_STOP_SEQUENCE) {
			debugC(3, kDebugLevelSound, "End of MIDI sequence (After reading delta-time)");
			_playing = false;

			midiObj->rewind();

			return;
		}

		// Separate byte into command and channel if it's a command byte.
		// Otherwise use running status (i.e. previously set command and channel).
		if (*p & 0x80) {
			cmd = *p++;
			ch = cmd & 0x0f;
			cmd >>= 4;
		}

		switch (cmd) {
		case MIDI_CMD_NOTE_OFF:
			parm1 = *p++;
			parm2 = *p++;
			midiNoteOff(ch, parm1, parm2);
			break;
		case MIDI_CMD_NOTE_ON:
			parm1 = *p++;
			parm2 = *p++;
			midiNoteOn(ch, parm1, parm2);
			break;
		case MIDI_CMD_CONTROLLER:
			parm1 = *p++;
			parm2 = *p++;
			midiController(ch, parm1, parm2);
			break;
		case MIDI_CMD_PROGRAM_CHANGE:
			parm1 = *p++;
			midiProgramChange(ch, parm1);
			break;
		case MIDI_CMD_PITCH_WHEEL:
			parm1 = *p++;
			parm2 = *p++;

			uint16 wheelPos = ((parm2 & 0x7F) << 7) | (parm1 & 0x7F); // 14-bit value
			midiPitchWheel(wheelPos);
			break;
		}
	}
Example #4
0
void SoundGen2GS::advanceMidiPlayer() {
	if (_disableMidi)
		return;

	const uint8 *p;
	uint8 parm1, parm2;
	static uint8 cmd, chn;

	if (_playingSound == -1 || _vm->_game.sounds[_playingSound] == NULL) {
		warning("Error playing Apple IIGS MIDI sound resource");
		_playing = false;
		return;
	}

	IIgsMidi *midiObj = (IIgsMidi *) _vm->_game.sounds[_playingSound];

	_ticks++;
	_playing = true;
	p = midiObj->getPtr();

	while (true) {
		// Check for end of MIDI sequence marker (Can also be here before delta-time)
		if (*p == MIDI_STOP_SEQUENCE) {
			debugC(3, kDebugLevelSound, "End of MIDI sequence (Before reading delta-time)");
			_playing = false;
			midiObj->rewind();
			return;
		}
		if (*p == MIDI_TIMER_SYNC) {
			debugC(3, kDebugLevelSound, "Timer sync");
			p++; // Jump over the timer sync byte as it's not needed
			continue;
		}

		// Check for delta time
		uint8 delta = *p;
		if (midiObj->_ticks + delta > _ticks)
			break;
		midiObj->_ticks += delta;
		p++;

		// Check for end of MIDI sequence marker (This time it after reading delta-time)
		if (*p == MIDI_STOP_SEQUENCE) {
			debugC(3, kDebugLevelSound, "End of MIDI sequence (After reading delta-time)");
			_playing = false;
			midiObj->rewind();
			return;
		}

		// Separate byte into command and channel if it's a command byte.
		// Otherwise use running status (i.e. previously set command and channel).
		if (*p & 0x80) {
			cmd = *p++;
			chn = cmd & 0x0f;
			cmd >>= 4;
		}

		switch (cmd) {
		case MIDI_NOTE_OFF:
			parm1 = *p++;
			parm2 = *p++;
			debugC(3, kDebugLevelSound, "channel %X: note off (key = %d, velocity = %d)", chn, parm1, parm2);
			midiNoteOff(chn, parm1, parm2);
			break;
		case MIDI_NOTE_ON:
			parm1 = *p++;
			parm2 = *p++;
			debugC(3, kDebugLevelSound, "channel %X: note on (key = %d, velocity = %d)", chn, parm1, parm2);
			midiNoteOn(chn, parm1, parm2);
			break;
		case MIDI_CONTROLLER:
			parm1 = *p++;
			parm2 = *p++;
			debugC(3, kDebugLevelSound, "channel %X: controller %02X = %02X", chn, parm1, parm2);
			// The tested Apple IIGS AGI MIDI resources only used
			// controllers 0 (Bank select?), 7 (Volume) and 64 (Sustain On/Off).
			// Controller 0's parameter was in range 94-127,
			// controller 7's parameter was in range 0-127 and
			// controller 64's parameter was always 0 (i.e. sustain off).
			switch (parm1) {
			case 7:
				_channels[chn].setVolume(parm2);
				break;
			}
			break;
		case MIDI_PROGRAM_CHANGE:
			parm1 = *p++;
			debugC(3, kDebugLevelSound, "channel %X: program change %02X", chn, parm1);
			_channels[chn].setInstrument(getInstrument(parm1));
			break;
		case MIDI_PITCH_WHEEL:
			parm1 = *p++;
			parm2 = *p++;
			debugC(3, kDebugLevelSound, "channel %X: pitch wheel (unimplemented)", chn);
			break;

		default:
			debugC(3, kDebugLevelSound, "channel %X: unimplemented command %02X", chn, cmd);
			break;
		}
	}
Example #5
0
void midiNoteOff(int note)
{
        midiNoteOn(note, 0);
}