From 015ecabb566d64acf9807d262565cf46d453b294 Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Sat, 20 Sep 2008 15:12:58 +0300 Subject: [PATCH] Import jackctlmmc-0 (from released tarball) --- GNUmakefile | 16 +++++ main.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 GNUmakefile create mode 100644 main.c diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..42edaea --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,16 @@ +CFLAGS := $(strip $(shell pkg-config --cflags lash-1.0)) -Wall -Werror +LIBS := $(strip $(shell pkg-config --libs lash-1.0)) + +OBJECTS=main.o + +# rebuild by default, until we have dependecies +default: rebuild + +jackctlmmc: $(OBJECTS) + gcc $(LIBS) -o $@ $(OBJECTS) + +clean: + rm -f jackctlmmc + rm -rf *.o + +rebuild: clean jackctlmmc diff --git a/main.c b/main.c new file mode 100644 index 0000000..de14af3 --- /dev/null +++ b/main.c @@ -0,0 +1,214 @@ +#include +#include +#include + +#include +#include +#include +#include + +snd_seq_t * g_seq_ptr; +lash_client_t * g_lashc; +jack_client_t * g_jack_client; + +/* a flag which will be set by our signal handler when it's time to exit */ +int quit = 0; + +/* the signal handler */ +void +signalled(int signal) +{ + quit = 1; +} + +void +process_lash_event(lash_event_t * event_ptr) +{ + enum LASH_Event_Type type; + const char * str; + + type = lash_event_get_type(event_ptr); + str = lash_event_get_string(event_ptr); + + switch (type) + { + case LASH_Quit: + printf("LASH_Quit received.\n"); + g_lashc = NULL; + quit = 1; + break; + case LASH_Save_File: + case LASH_Restore_File: + case LASH_Save_Data_Set: + default: + printf("LASH Event. Type = %u, string = \"%s\"\n", + (unsigned int)type, + (str == NULL)?"":str); + } +} + +void +process_lash_config(lash_config_t * config_ptr) +{ + const char * key; + const void * data; + size_t data_size; + + key = lash_config_get_key(config_ptr); + data = lash_config_get_value(config_ptr); + data_size = lash_config_get_value_size(config_ptr); + + printf("LASH Config. Key = \"%s\"\n", key); +} + +int +main(int argc, char *argv[]) +{ + int ret; + lash_event_t * lash_event_ptr; + lash_config_t * lash_config_ptr; + snd_seq_port_info_t * seq_port_info = NULL; + snd_seq_event_t * seq_event_ptr; + int npfd; + struct pollfd * pfd; + + /* setup our signal handler signalled() above, so we can exit cleanly (see end of main()) */ + signal(SIGINT, signalled); + + /* LASH setup */ + g_lashc = lash_init( + lash_extract_args(&argc, &argv), + "jackctlmmc", + 0, + LASH_PROTOCOL_VERSION); + + if (g_lashc == NULL) + { + printf("Failed to connect to LASH. Session management will not occur.\n"); + } + else + { + lash_event_ptr = lash_event_new_with_type(LASH_Client_Name); + lash_event_set_string(lash_event_ptr, "jackctlmmc"); + lash_send_event(g_lashc, lash_event_ptr); + } + + /* naturally we need to become a jack client :) */ + g_jack_client = jack_client_new("jackctlmmc"); + if (!g_jack_client) + { + printf("couldn't connect to jack server. Either it's not running or the client name is already taken\n"); + goto exit; + } + + lash_jack_client_name(g_lashc, "jackctlmmc"); + + /* ALSA sequencer initialisation */ + ret = snd_seq_open( + &g_seq_ptr, + "default", + SND_SEQ_OPEN_INPUT, + 0); + if (ret < 0) + { + printf("Cannot open sequncer, %s\n", snd_strerror(ret)); + goto close_jack; + } + + snd_seq_set_client_name(g_seq_ptr, "jackctlmmc"); + + lash_alsa_client_id(g_lashc, snd_seq_client_id(g_seq_ptr)); + + snd_seq_port_info_alloca(&seq_port_info); + + snd_seq_port_info_set_capability( + seq_port_info, + SND_SEQ_PORT_CAP_WRITE | + SND_SEQ_PORT_CAP_SUBS_WRITE); + snd_seq_port_info_set_type( + seq_port_info, + SND_SEQ_PORT_TYPE_APPLICATION); + snd_seq_port_info_set_midi_channels(seq_port_info, 16); + snd_seq_port_info_set_port_specified(seq_port_info, 1); + + snd_seq_port_info_set_name(seq_port_info, "midi in"); + snd_seq_port_info_set_port(seq_port_info, 0); + + ret = snd_seq_create_port(g_seq_ptr, seq_port_info); + if (ret < 0) + { + printf("Error creating ALSA sequencer port, %s\n", snd_strerror(ret)); + goto close_seq; + } + + /* tell jack that we are ready to do our thing */ + jack_activate(g_jack_client); + + npfd = snd_seq_poll_descriptors_count(g_seq_ptr, POLLIN); + pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd)); + snd_seq_poll_descriptors(g_seq_ptr, pfd, npfd, POLLIN); + + /* wait until this app receives a SIGINT (i.e. press ctrl-c in the terminal) see signalled() above */ + while(!quit) + { + if (poll(pfd, npfd, 250) > 0 && snd_seq_event_input(g_seq_ptr, &seq_event_ptr) >= 0) + { + if (seq_event_ptr->type == SND_SEQ_EVENT_SYSEX && + seq_event_ptr->data.ext.len == 6 && + ((unsigned char *)seq_event_ptr->data.ext.ptr)[0] == 0xF0 && + ((unsigned char *)seq_event_ptr->data.ext.ptr)[1] == 0x7F && + ((unsigned char *)seq_event_ptr->data.ext.ptr)[2] == 0x7F && /* All devices */ + ((unsigned char *)seq_event_ptr->data.ext.ptr)[3] == 0x06 && + ((unsigned char *)seq_event_ptr->data.ext.ptr)[5] == 0xF7) + { + switch (((char *)seq_event_ptr->data.ext.ptr)[4]) + { + case 1: /* stop */ + printf("MMC Stop -> JACK transport stop\n"); + jack_transport_stop(g_jack_client); + break; + case 2: /* play */ + printf("MMC Play -> JACK transport start\n"); + jack_transport_start(g_jack_client); + break; + case 5: /* rewind */ + printf("MMC Play -> JACK transport locate to 0\n"); + jack_transport_locate(g_jack_client, 0); + break; + } + } + } + + /* Process LASH events */ + while ((lash_event_ptr = lash_get_event(g_lashc)) != NULL) + { + process_lash_event(lash_event_ptr); + lash_event_destroy(lash_event_ptr); + } + + /* Process LASH configs */ + while ((lash_config_ptr = lash_get_config(g_lashc)) != NULL) + { + process_lash_config(lash_config_ptr); + lash_config_destroy(lash_config_ptr); + } + } + + /* so we shall quit, eh? ok, cleanup time. otherwise jack would probably produce an xrun + * on shutdown */ + jack_deactivate(g_jack_client); + +close_seq: + ret = snd_seq_close(g_seq_ptr); + if (ret < 0) + { + printf("Cannot close sequncer, %s\n", snd_strerror(ret)); + } + +close_jack: + /* shutdown cont. */ + jack_client_close(g_jack_client); + +exit: + return 0; +} -- 2.11.4.GIT