Exemplo n.º 1
0
void JVlibForm::init_seq() {
  if (seq) return;
  int err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0);
  check_snd("open sequencer", err);
  err = snd_seq_set_client_name(seq, "midi_player");
  check_snd("set client name", err);
  int client = snd_seq_client_id(seq);    // client # is 128 by default
  check_snd("get client id", client);
}
static void init_seq(void)
{
	int err;

	/* open sequencer */
	err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
	check_snd("open sequencer", err);

	/* set our client's name */
	err = snd_seq_set_client_name(seq, "aseqdump");
	check_snd("set client name", err);
}
Exemplo n.º 3
0
//  SLOTS
void JVlibForm::on_System_OpenMidi_button_clicked()
{
    disconnect_port();
//    close_seq();
    System_PlayMidi_button->setChecked(false);
    System_PlayMidi_button->setEnabled(false);
    System_PauseMidi_button->setEnabled(false);
    SysFilePlaying->clear();
    System_MIDI_Transpose->setValue(0);
    System_MIDI_KeySig->clear();
    MIDI_length_display->setText("00:00");
    QString fn = QFileDialog::getOpenFileName(this,"Open MIDI File",MIDI_dir,"Midi files (*.mid, *.MID);;Any (*.*)");
    if (fn.isEmpty())
        return;
    strcpy(playfile, fn.toAscii().data());
    SysFilePlaying->setText(fn);
    init_seq();
    if (!queue) queue = snd_seq_alloc_named_queue(seq, "midi_play");
    check_snd("create queue", queue);
    connect_port();
    all_events.clear();
    if (!parseFile(playfile)) {
        QMessageBox::critical(this, "MIDI Player", QString("Error parsing input file"));
        return;
    }   // parseFile
    System_MIDI_progressBar->setRange(0,all_events.back().tick);
    System_MIDI_progressBar->setTickInterval(song_length_seconds<240? all_events.back().tick/song_length_seconds*10 : all_events.back().tick/song_length_seconds*30);
    System_MIDI_progressBar->setTickPosition(QSlider::TicksAbove);
    MIDI_length_display->setText(QString::number(static_cast<int>(song_length_seconds/60)).rightJustified(2,'0') + ":" + QString::number(static_cast<int>(song_length_seconds)%60).rightJustified(2,'0'));
    System_PlayMidi_button->setEnabled(true);
    System_MIDI_Transpose->setEnabled(true);
}   // end on_System_OpenMidi_button_clicked
Exemplo n.º 4
0
void JVlibForm::connect_port() {
    if (seq && strlen(SEQ_dev)) {
        //  create_source_port
        snd_seq_port_info_t *pinfo;
        snd_seq_port_info_alloca(&pinfo);
        // the first created port is 0 anyway, but let's make sure ...
        snd_seq_port_info_set_port(pinfo, 0);
        snd_seq_port_info_set_port_specified(pinfo, 1);
        snd_seq_port_info_set_name(pinfo, "midi_player");
        snd_seq_port_info_set_capability(pinfo, 0);
        snd_seq_port_info_set_type(pinfo,
               SND_SEQ_PORT_TYPE_MIDI_GENERIC |
               SND_SEQ_PORT_TYPE_APPLICATION);
        int err = snd_seq_create_port(seq, pinfo);
        check_snd("create port", err);
	
        ports = (snd_seq_addr_t *)realloc(ports, sizeof(snd_seq_addr_t));
        err = snd_seq_parse_address(seq, &ports[0], SEQ_dev);
        if (err < 0) {
            QMessageBox::critical(this, "MIDI Player", QString("Invalid port%1\n%2") .arg(SEQ_dev) .arg(snd_strerror(err)));
            return;
        }
        err = snd_seq_connect_to(seq, 0, ports[0].client, ports[0].port);
        if (err < 0 && err!= -16)
            QMessageBox::critical(this, "MIDI Player", QString("%4 Cannot connect to port %1:%2 - %3") .arg(ports[0].client) .arg(ports[0].port) .arg(strerror(errno)) .arg(err));
    }
}   // end connect_port
Exemplo n.º 5
0
static int init_seq(ClientData clientData, Tcl_Interp *interp)
{
  if (seq == NULL) {
    int err;

    /* open sequencer */
    err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
    if (check_snd(clientData, interp, "open sequencer", err) < 0) {
      return TCL_ERROR;
    }

    /* set our client's name */
    err = snd_seq_set_client_name(seq, "awtcl");
    if (check_snd(clientData, interp, "set client name", err) != TCL_OK) {
      return TCL_ERROR;
    }
  }
  return TCL_OK;
}
static void create_port(void)
{
	int err;

	err = snd_seq_create_simple_port(seq, "aseqdump",
					 SND_SEQ_PORT_CAP_WRITE |
					 SND_SEQ_PORT_CAP_SUBS_WRITE,
					 SND_SEQ_PORT_TYPE_MIDI_GENERIC |
					 SND_SEQ_PORT_TYPE_APPLICATION);
	check_snd("create port", err);
}
Exemplo n.º 7
0
void JVlibForm::on_System_PlayMidi_button_toggled(bool checked) {
    if (checked) {
	seqTimer = new QTimer(this);
        System_PauseMidi_button->setEnabled(true);
        System_OpenMidi_button->setEnabled(false);
        System_PlayMidi_button->setText("Stop");
	System_MIDI_progressBar->setEnabled(true);
        connect_port();
        // queue won't actually start until it is drained
        int err = snd_seq_start_queue(seq, queue, NULL);
        check_snd("start queue", err);
	System_PlayMidi_status->on();
        connect(JVlibForm::seqTimer, SIGNAL(timeout()), this, SLOT(tickDisplay()));
        seqTimer->start(100);
	startPlayer(0);
    }
    else {
        if (seqTimer->isActive()) {
            disconnect(JVlibForm::seqTimer, SIGNAL(timeout()), this, SLOT(tickDisplay()));
            seqTimer->stop();
	    delete seqTimer;
        }
        snd_seq_stop_queue(seq,queue,NULL);
        snd_seq_drain_output(seq);
	stopPlayer();
	stop_sound();
        disconnect_port();
	System_PlayMidi_status->off();
	System_MIDI_progressBar->blockSignals(true);
        System_MIDI_progressBar->setValue(0);
	System_MIDI_progressBar->blockSignals(false);
        MIDI_time_display->setText("00:00");
        if (System_PauseMidi_button->isChecked()) {
            System_PauseMidi_button->blockSignals(true);
            System_PauseMidi_button->setChecked(false);
            System_PauseMidi_button->blockSignals(false);
            System_PauseMidi_button->setText("Pause");
        }
        System_PauseMidi_button->setEnabled(false);
        System_PlayMidi_button->setText("Play");
        System_OpenMidi_button->setEnabled(true);
	System_MIDI_Transpose->setEnabled(true);
	System_MIDI_progressBar->setEnabled(false);
	event_num=0;
    }
}   // end on_System_PlayMidi_button_toggled
int main(int argc, char *argv[])
{
	static const char short_options[] = "hVlp:";
	static const struct option long_options[] = {
		{"help", 0, NULL, 'h'},
		{"version", 0, NULL, 'V'},
		{"list", 0, NULL, 'l'},
		{"port", 1, NULL, 'p'},
		{ }
	};

	int do_list = 0;
	struct pollfd *pfds;
	int npfds;
	int c, err;

	init_seq();

	while ((c = getopt_long(argc, argv, short_options,
				long_options, NULL)) != -1) {
		switch (c) {
		case 'h':
			help(argv[0]);
			return 0;
		case 'V':
			version();
			return 0;
		case 'l':
			do_list = 1;
			break;
		case 'p':
			parse_ports(optarg);
			break;
		default:
			help(argv[0]);
			return 1;
		}
	}
	if (optind < argc) {
		help(argv[0]);
		return 1;
	}

	if (do_list) {
		list_ports();
		return 0;
	}

	create_port();
	connect_ports();

	err = snd_seq_nonblock(seq, 1);
	check_snd("set nonblock mode", err);
	
	if (port_count > 0)
		printf("Waiting for data.");
	else
		printf("Waiting for data at port %d:0.",
		       snd_seq_client_id(seq));
	printf(" Press Ctrl+C to end.\n");
	printf("Source  Event                  Ch  Data\n");
	
	signal(SIGINT, sighandler);
	signal(SIGTERM, sighandler);

	npfds = snd_seq_poll_descriptors_count(seq, POLLIN);
	pfds = alloca(sizeof(*pfds) * npfds);
	for (;;) {
		snd_seq_poll_descriptors(seq, pfds, npfds, POLLIN);
		if (poll(pfds, npfds, -1) < 0)
			break;
		do {
			snd_seq_event_t *event;
			err = snd_seq_event_input(seq, &event);
			if (err < 0)
				break;
			if (event)
				dump_event(event);
		} while (err > 0);
		fflush(stdout);
		if (stop)
			break;
	}

	snd_seq_close(seq);
	return 0;
}
Exemplo n.º 9
0
void MIDI_PLAYER::play_midi(unsigned int startTick) {
    int end_delay = 2;
    int err;
    // set data in (snd_seq_event_t ev) and output the event
    // common settings for all events
    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);
    ev.queue = queue;
    ev.source.port = 0;
    ev.flags = SND_SEQ_TIME_STAMP_TICK;
    // parse each event, already in sort order by 'tick' from parse_file
    for (std::vector<event>::iterator Event=all_events.begin(); Event!=all_events.end(); ++Event)  {
        // skip over everything except TEMPO, CONTROLLER, PROGRAM, ChannelPressure and SysEx changes until startTick is reached.
        if (Event->tick<startTick &&
            (Event->type!=SND_SEQ_EVENT_TEMPO ||
             Event->type!=SND_SEQ_EVENT_CONTROLLER ||
             Event->type!=SND_SEQ_EVENT_PGMCHANGE ||
             Event->type!=SND_SEQ_EVENT_CHANPRESS ||
             Event->type!=SND_SEQ_EVENT_SYSEX))
	{
            continue;
	}
        ev.time.tick = Event->tick;
        ev.type = Event->type;
//        ev.dest = ports[Event->port];
        ev.dest = ports[0];
        switch (ev.type) {
        case SND_SEQ_EVENT_NOTEON:
        case SND_SEQ_EVENT_NOTEOFF:
        case SND_SEQ_EVENT_KEYPRESS:
            snd_seq_ev_set_fixed(&ev);
            ev.data.note.channel = Event->data.d[0];
            ev.data.note.note = Event->data.d[1];
            ev.data.note.velocity = Event->data.d[2];
            break;
        case SND_SEQ_EVENT_CONTROLLER:
            snd_seq_ev_set_fixed(&ev);
            ev.data.control.channel = Event->data.d[0];
            ev.data.control.param = Event->data.d[1];
            ev.data.control.value = Event->data.d[2];
            break;
        case SND_SEQ_EVENT_PGMCHANGE:
        case SND_SEQ_EVENT_CHANPRESS:
            snd_seq_ev_set_fixed(&ev);
            ev.data.control.channel = Event->data.d[0];
            ev.data.control.value = Event->data.d[1];
            break;
        case SND_SEQ_EVENT_PITCHBEND:
            snd_seq_ev_set_fixed(&ev);
            ev.data.control.channel = Event->data.d[0];
            ev.data.control.value =
                ((Event->data.d[1]) |
                 ((Event->data.d[2]) << 7)) - 0x2000;
            break;
        case SND_SEQ_EVENT_SYSEX:
            snd_seq_ev_set_variable(&ev, Event->data.length, &Event->sysex);
            break;
        case SND_SEQ_EVENT_TEMPO:
            snd_seq_ev_set_fixed(&ev);
            ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
            ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
            ev.data.queue.queue = queue;
            ev.data.queue.param.value = Event->data.tempo;
            break;
        default:
            QMessageBox::critical(this, "MIDI Player", QString("Invalid event type %1") .arg(ev.type));
        }   // end SWITCH ev.type
        // do the actual output of the event to the MIDI queue
        // this blocks when the output pool has been filled
        err = snd_seq_event_output(seq, &ev);
        check_snd("output event", err);
    }	// end for all_events iterator

    // schedule queue stop at end of song
    snd_seq_ev_set_fixed(&ev);
    ev.type = SND_SEQ_EVENT_STOP;
    ev.time.tick = all_events.back().tick;
    ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
    ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
    ev.data.queue.queue = queue;
    err = snd_seq_event_output(seq, &ev);
    check_snd("output event", err);
    // make sure that the sequencer sees all our events
    err = snd_seq_drain_output(seq);
    check_snd("drain output", err);

    // There are three possibilities for how to wait until all events have been played:
    // 1) send an event back to us (like pmidi does), and wait for it;
    // 2) wait for the EVENT_STOP notification for our queue which is sent
    //    by the system timer port (this would require a subscription);
    // 3) wait until the output pool is empty.
    // The last is the simplest.
    err = snd_seq_sync_output_queue(seq);
    check_snd("sync output", err);
    // give the last notes time to die away
    if (end_delay > 0)
        sleep(end_delay);
}   // end play_midi