Example #1
0
int main(int argc, char* argv[])
{


    char filename[] = "doom-e1m1.mid";
      RtMidiOut *midiout = new RtMidiOut();
    string portName;
    
    nPorts = midiout->getPortCount();
 
    if(argc < 2)    {
        if ( nPorts == 0 )     cout << "No ports available!\n";
        for ( unsigned int i=0; i<nPorts; i++ ) {
            try { portName = midiout->getPortName(i);    }
             catch (RtError &error) {error.printMessage(); }
            cout << "  Output Port #" << i+1 << ": " << portName << '\n';
        }
    }else{
        int port = atoi(argv[1]);
          //midiout->openPort( port );

        cout << "Opening midi" << endl;    
        char *filef = argv[2];
        if(argc == 3)
            parser.Open(filef);
        else
            parser.Open(filename);
    
        tickspersecond = ( (parser.bpm / 30.0) * ( parser.tpb));
        cout << " Ticks per second: " << tickspersecond << endl;
        
        (void) signal(SIGINT, finish);
        tickcount = 0;

        Sequencer sequencers[parser.numtracks];
        SequencerRunning = true;
        for(int i=0;i<parser.numtracks;i++)    {
            sequencers[i].StartSequencer(i, &parser.mididata.tracks[i], port);
            sf::Sleep(0.01f);
        }
        sf::Sleep(1);
        timer.Reset();
        while(run)    {
            timecount = timer.GetElapsedTime();
            tickcount += timecount * tickspersecond;
            timer.Reset();
            //sf::Sleep(0.0001f);
        }
    }
    delete midiout;    
    finish(0);
    return 0;
}
Example #2
0
void SoundGenMIDI::play(int resnum) {
	MIDISound *track;

	stop();

	_isGM = true;

	track = (MIDISound *)_vm->_game.sounds[resnum];

	// Convert AGI Sound data to MIDI
	int midiMusicSize = convertSND2MIDI(track->_data, &_midiData);

	MidiParser *parser = MidiParser::createParser_SMF();
	if (parser->loadMusic(_midiData, midiMusicSize)) {
		parser->setTrack(0);
		parser->setMidiDriver(this);
		parser->setTimerRate(_driver->getBaseTempo());
		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);

		_parser = parser;

		syncVolume();

		_isPlaying = true;
	} else {
		delete parser;
	}
}
Example #3
0
void MidiMusicPlayer::playXMIDI(uint32 size, bool loop) {
	// It seems like not all music (the main menu music, for instance) set
	// all the instruments explicitly. That means the music will sound
	// different, depending on which music played before it. This appears
	// to be a genuine glitch in the original. For consistency, reset all
	// instruments to the default one (piano).

	for (int i = 0; i < 16; i++) {
		_driver->send(0xC0 | i, 0, 0);
	}

	// Load XMID resource data

	MidiParser *parser = MidiParser::createParser_XMIDI();
	if (parser->loadMusic(g_midiBuffer.pDat, size)) {
		parser->setTrack(0);
		parser->setMidiDriver(this);
		parser->setTimerRate(getBaseTempo());
		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
		parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);

		_parser = parser;

		_isLooping = loop;
		_isPlaying = true;
	} else {
		delete parser;
	}
}
Example #4
0
void MusicPlayer::playSMF(int track, bool loop) {
	Common::StackLock lock(_mutex);

	if (_isPlaying && track == _track) {
		debugC(2, kDraciSoundDebugLevel, "Already plaing track %d", track);
		return;
	}

	stop();

	_isGM = true;

	// Load MIDI resource data
	Common::File musicFile;
	Common::String musicFileName = Common::String::format(_pathMask.c_str(), track);
	musicFile.open(musicFileName.c_str());
	if (!musicFile.isOpen()) {
		debugC(2, kDraciSoundDebugLevel, "Cannot open track %d", track);
		return;
	}
	int midiMusicSize = musicFile.size();
	free(_midiData);
	_midiData = (byte *)malloc(midiMusicSize);
	musicFile.read(_midiData, midiMusicSize);
	musicFile.close();

	MidiParser *parser = MidiParser::createParser_SMF();
	if (parser->loadMusic(_midiData, midiMusicSize)) {
		parser->setTrack(0);
		parser->setMidiDriver(this);
		parser->setTimerRate(_driver->getBaseTempo());
		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);

		_parser = parser;

		syncVolume();

		_isLooping = loop;
		_isPlaying = true;
		_track = track;
		debugC(2, kDraciSoundDebugLevel, "Playing track %d", track);
	} else {
		debugC(2, kDraciSoundDebugLevel, "Cannot play track %d", track);
		delete parser;
	}
}
Example #5
0
TestExitStatus MidiTests::playMidiMusic() {
	Testsuite::clearScreen();
	Common::String info = "Testing Midi Sound output.\n"
						  "Here, We generate some Music by using the Midi Driver selected in the GUI.\n"
						  "You should expect to hear that. The initialization may take some time.\n";

	if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
		Testsuite::logPrintf("Info! Skipping test : Play Midi Music\n");
		return kTestSkipped;
	}

	MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB);
	// Create a driver instance
	MidiDriver *driver = MidiDriver::createMidi(dev);
	// Create a SMF parser
	MidiParser *smfParser = MidiParser::createParser_SMF();
	// Open the driver
	int errCode = driver->open();

	if (errCode) {
		Common::String errMsg = driver->getErrorName(errCode);
		Testsuite::writeOnScreen(errMsg, Common::Point(0, 100));
		Testsuite::logPrintf("Error! %s", errMsg.c_str());
		return kTestFailed;
	}

	Testsuite::logDetailedPrintf("Info! Midi: Succesfully opened the driver\n");

	Common::MemoryWriteStreamDynamic ws(DisposeAfterUse::YES);
	loadMusicInMemory(&ws);

	// start playing
	if (smfParser->loadMusic(ws.getData(), ws.size())) {
		smfParser->setTrack(0);
		smfParser->setMidiDriver(driver);
		smfParser->setTimerRate(driver->getBaseTempo());
		driver->setTimerCallback(smfParser, MidiParser::timerCallback);
		Testsuite::logDetailedPrintf("Info! Midi: Parser Successfully loaded Music data.\n");
		if (smfParser->isPlaying()) {
			Testsuite::writeOnScreen("Playing Midi Music, Click to end.", Common::Point(0, 100));
			Testsuite::logDetailedPrintf("Info! Midi: Playing music!\n");
		}
	}


	// Play until track ends or an exit is requested.
	waitForMusicToPlay(smfParser);

	// Done. Clean up.
	smfParser->unloadMusic();
	driver->setTimerCallback(NULL, NULL);
	driver->close();
	delete smfParser;
	delete driver;

	if (Testsuite::handleInteractiveInput("Were you able to hear the music as described?", "Yes", "No", kOptionRight)) {
		Testsuite::logDetailedPrintf("Error! Midi: Can't play Music\n");
		return kTestFailed;
	}
	return kTestPassed;
}
Example #6
0
void MidiMusicPlayer::playSEQ(uint32 size, bool loop) {
	// MIDI.DAT holds the file names in DW1 PSX
	Common::String baseName((char *)g_midiBuffer.pDat, size);
	Common::String seqName = baseName + ".SEQ";

	// TODO: Load the instrument bank (<baseName>.VB and <baseName>.VH)

	Common::File seqFile;
	if (!seqFile.open(seqName))
		error("Failed to open SEQ file '%s'", seqName.c_str());

	if (seqFile.readUint32LE() != MKTAG('S', 'E', 'Q', 'p'))
		error("Failed to find SEQp tag");

	// Make sure we don't have a SEP file (with multiple SEQ's inside)
	if (seqFile.readUint32BE() != 1)
		error("Can only play SEQ files, not SEP");

	uint16 ppqn = seqFile.readUint16BE();
	uint32 tempo = seqFile.readUint16BE() << 8;
	tempo |= seqFile.readByte();
	/* uint16 beat = */ seqFile.readUint16BE();

	// SEQ is directly based on SMF and we'll use that to our advantage here
	// and convert to SMF and then use the SMF MidiParser.

	// Calculate the SMF size we'll need
	uint32 dataSize = seqFile.size() - 15;
	uint32 actualSize = dataSize + 7 + 22;

	// Resize the buffer if necessary
	if (g_midiBuffer.size < actualSize) {
		g_midiBuffer.pDat = (byte *)realloc(g_midiBuffer.pDat, actualSize);
		assert(g_midiBuffer.pDat);
	}

	// Now construct the header
	WRITE_BE_UINT32(g_midiBuffer.pDat, MKTAG('M', 'T', 'h', 'd'));
	WRITE_BE_UINT32(g_midiBuffer.pDat + 4, 6); // header size
	WRITE_BE_UINT16(g_midiBuffer.pDat + 8, 0); // type 0
	WRITE_BE_UINT16(g_midiBuffer.pDat + 10, 1); // one track
	WRITE_BE_UINT16(g_midiBuffer.pDat + 12, ppqn);
	WRITE_BE_UINT32(g_midiBuffer.pDat + 14, MKTAG('M', 'T', 'r', 'k'));
	WRITE_BE_UINT32(g_midiBuffer.pDat + 18, dataSize + 7); // SEQ data size + tempo change event size

	// Add in a fake tempo change event
	WRITE_BE_UINT32(g_midiBuffer.pDat + 22, 0x00FF5103); // no delta, meta event, tempo change, param size = 3
	WRITE_BE_UINT16(g_midiBuffer.pDat + 26, tempo >> 8);
	g_midiBuffer.pDat[28] = tempo & 0xFF;

	// Now copy in the rest of the events
	seqFile.read(g_midiBuffer.pDat + 29, dataSize);
	seqFile.close();

	MidiParser *parser = MidiParser::createParser_SMF();
	if (parser->loadMusic(g_midiBuffer.pDat, actualSize)) {
		parser->setTrack(0);
		parser->setMidiDriver(this);
		parser->setTimerRate(getBaseTempo());
		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
		parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);

		_parser = parser;

		_isLooping = loop;
		_isPlaying = true;
	} else {
		delete parser;
	}
}