Пример #1
0
void midi_engine_stop(void)
{
        struct midi_provider *n, *p;
        struct midi_port *q;

        if (!_connected) return;
        if (!midi_mutex) return;

        SDL_mutexP(midi_mutex);
        for (n = port_providers; n;) {
                p = n->next;

                q = NULL;
                while (midi_port_foreach(p, &q)) {
                        midi_port_unregister(q->num);
                }

                if (n->thread) {
                        SDL_KillThread(n->thread);
                }
                free(n->name);
                free(n);
                n = p;
        }
        _connected = 0;
        SDL_mutexV(midi_mutex);
}
Пример #2
0
void midi_send_flush(void)
{
        struct midi_port *ptr = NULL;
        int need_explicit_flush = 0;

        if (!midi_record_mutex || !midi_play_mutex) return;

        while (midi_port_foreach(NULL, &ptr)) {
                if ((ptr->io & MIDI_OUTPUT)) {
                        if (ptr->drain) ptr->drain(ptr);
                        else if (ptr->send_now) need_explicit_flush=1;
                }
        }

        /* no need for midi sync huzzah; driver does it for us... */
        if (!need_explicit_flush) return;

        if (!midi_queue_thread) {
                midi_queue_thread = SDL_CreateThread(_midi_queue_run, NULL);
                if (midi_queue_thread) {
                        log_appendf(3, "Started MIDI queue thread");
                } else {
                        log_appendf(2, "ACK: Couldn't start MIDI thread; things are likely going to go boom!");
                }
        }

        SDL_mutexP(midi_play_mutex);
        SDL_CondSignal(midi_play_cond);
        SDL_mutexV(midi_play_mutex);
}
Пример #3
0
static int _midi_send_unlocked(const unsigned char *data, unsigned int len, unsigned int delay,
                        int from)
{
        struct midi_port *ptr = NULL;
        int need_timer = 0;
#if 0
        unsigned int i;
printf("MIDI: ");
        for (i = 0; i < len; i++) {
                printf("%02x ", data[i]);
        }
puts("");
fflush(stdout);
#endif
        if (from == 0) {
                /* from == 0 means from immediate; everyone plays */
                while (midi_port_foreach(NULL, &ptr)) {
                        if ((ptr->io & MIDI_OUTPUT)) {
                                if (ptr->send_now)
                                        ptr->send_now(ptr, data, len, 0);
                                else if (ptr->send_later)
                                        ptr->send_later(ptr, data, len, 0);
                        }
                }
        } else if (from == 1) {
                /* from == 1 means from buffer-flush; only "now" plays */
                while (midi_port_foreach(NULL, &ptr)) {
                        if ((ptr->io & MIDI_OUTPUT)) {
                                if (ptr->send_now)
                                        ptr->send_now(ptr, data, len, 0);
                        }
                }
        } else {
                /* from == 2 means from buffer-write; only "later" plays */
                while (midi_port_foreach(NULL, &ptr)) {
                        if ((ptr->io & MIDI_OUTPUT)) {
                                if (ptr->send_later)
                                        ptr->send_later(ptr, data, len, delay);
                                else if (ptr->send_now)
                                        need_timer = 1;
                        }
                }
        }
        return need_timer;
}
Пример #4
0
static void _readin(struct midi_provider *p, int en, int fd)
{
	struct midi_port *ptr, *src;
	static unsigned char buffer[65536];
	static struct sockaddr_in asin;
	unsigned slen = sizeof(asin);
	int r;

	r = recvfrom(fd, buffer, sizeof(buffer), 0,
		(struct sockaddr *)&asin, &slen);
	if (r > 0) {
		ptr = src = NULL;
		while (midi_port_foreach(p, &ptr)) {
			int n = INT_SHAPED_PTR(ptr->userdata);
			if (n == en) src = ptr;
		}
		midi_received_cb(src, buffer, r);
	}
}
Пример #5
0
static void _ip_poll(struct midi_provider *p)
{
	static int last_buildout = 0;
	struct midi_port *ptr;
	char *buffer;
	long i = 0;
	long m;

	SDL_mutexP(blocker);
	m = (volatile int)real_num_ports;
	if (m < last_buildout) {
		ptr = NULL;
		while (midi_port_foreach(p, &ptr)) {
			i = INT_SHAPED_PTR(ptr->userdata);
			if (i >= m) {
				midi_port_unregister(ptr->num);
				//port_top[i] (the address where ptr points to) is freed in midi_port_unregister.
				//So clear it to avoid midi_port_foreach crashing on next round
				ptr = NULL;
			}
		}
		last_buildout = m;
	} else if (m > last_buildout) {
		for (i = last_buildout; i < m; i++) {
			buffer = NULL;
			if (asprintf(&buffer, " Multicast/IP MIDI %lu", i+1) == -1) {
				perror("asprintf");
				exit(255);
			}
			if (!buffer) {
				perror("asprintf");
				exit(255);
			}
			midi_port_register(p, MIDI_INPUT | MIDI_OUTPUT, buffer,
					PTR_SHAPED_INT((intptr_t)i), 0);
		}
		last_buildout = m;
	}
	SDL_mutexV(blocker);
}
Пример #6
0
int midi_need_flush(void)
{
        struct midi_port *ptr;
        int need_explicit_flush = 0;
        int i;

        if (!midi_record_mutex || !midi_play_mutex) return 0;

        ptr = NULL;

        while (midi_port_foreach(NULL, &ptr)) {
                if ((ptr->io & MIDI_OUTPUT)) {
                        if (!ptr->drain && ptr->send_now)
                                need_explicit_flush = 1;
                }
        }
        if (!need_explicit_flush) return 0;

        for (i = 0; i < qlen; i++) {
                if (qq[i].used) return 1;
        }

        return 0;
}
Пример #7
0
void cfg_save_midi(cfg_file_t *cfg)
{
        struct cfg_section *c;
        struct midi_provider *p;
        struct midi_port *q;
        midi_config_t *md, *mc;
        char buf[33];
        char *ss;
        int i, j;

        CFG_SET_MI(flags);
        CFG_SET_MI(pitch_depth);
        CFG_SET_MI(amplification);
        CFG_SET_MI(c5note);

        song_lock_audio();
        md = &default_midi_config;

        /* overwrite default */
        mc = &current_song->midi_config;
        memcpy(md, mc, sizeof(midi_config_t));

        cfg_set_string(cfg,"MIDI","start", md->start);
        cfg_set_string(cfg,"MIDI","stop", md->stop);
        cfg_set_string(cfg,"MIDI","tick", md->tick);
        cfg_set_string(cfg,"MIDI","note_on", md->note_on);
        cfg_set_string(cfg,"MIDI","note_off", md->note_off);
        cfg_set_string(cfg,"MIDI","set_volume", md->set_volume);
        cfg_set_string(cfg,"MIDI","set_panning", md->set_panning);
        cfg_set_string(cfg,"MIDI","set_bank", md->set_bank);
        cfg_set_string(cfg,"MIDI","set_program", md->set_program);
        for (i = 0; i < 16; i++) {
                snprintf(buf, 32, "SF%X", i);
                cfg_set_string(cfg, "MIDI", buf, md->sfx[i]);
        }
        for (i = 0; i < 128; i++) {
                snprintf(buf, 32, "Z%02X", i + 0x80);
                cfg_set_string(cfg, "MIDI", buf, md->zxx[i]);
        }
        song_unlock_audio();

        /* write out only enabled midi ports */
        i = 1;
        SDL_mutexP(midi_mutex);
        q = NULL;
        for (p = port_providers; p; p = p->next) {
                while (midi_port_foreach(p, &q)) {
                        ss = q->name;
                        if (!ss) continue;
                        while (isspace(*ss)) ss++;
                        if (!*ss) continue;
                        if (!q->io) continue;

                        snprintf(buf, 32, "MIDI Port %d", i); i++;
                        cfg_set_string(cfg, buf, "name", ss);
                        ss = p->name;
                        if (ss) {
                                while (isspace(*ss)) ss++;
                                if (*ss) {
                                        cfg_set_string(cfg, buf, "provider", ss);
                                }
                        }
                        cfg_set_number(cfg, buf, "input", q->io & MIDI_INPUT ? 1 : 0);
                        cfg_set_number(cfg, buf, "output", q->io & MIDI_OUTPUT ? 1 : 0);
                }
        }
        //TODO: Save number of MIDI-IP ports
        SDL_mutexV(midi_mutex);

        /* delete other MIDI port sections */
        for (c = cfg->sections; c; c = c->next) {
                j = -1;
                sscanf(c->name, "MIDI Port %d", &j);
                if (j < i) continue;
                c->omit = 1;
        }

}