Advertisement
MegaLoler

LaunchSEQ

Mar 17th, 2015
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 28.23 KB | None | 0 0
  1. // by megaloler!  (megaloler9000@gmail.com)
  2. // a custom 100% midi-controlled live loop-based sequencer for the launchkey mini!
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <signal.h>
  8. #include <alsa/asoundlib.h>
  9.  
  10. #define ALSA_CLIENT_NAME "LaunchSEQ"
  11.  
  12. #define MAX_PATTERN_EVENTS 4096
  13. #define MAX_SONG_PATTERNS 16
  14. #define MAX_SONG_SCENES 128
  15. #define MAX_SONG_PATCHES 128
  16.  
  17. #define MAX_QUEUE_SIZE 8192
  18.  
  19. #define METRONOME_PULSE_FRAMES_PER_BEAT 16
  20.  
  21. typedef struct
  22. {
  23.     int patch;
  24.     int events_length;
  25.     snd_seq_event_t events[MAX_PATTERN_EVENTS];
  26. } Pattern;
  27.  
  28. typedef struct
  29. {
  30.     int scene_pattern_masks[MAX_SONG_SCENES];
  31.     Pattern patterns[MAX_SONG_PATTERNS];
  32.    
  33.     int measures_per_pattern;
  34.     int beats_per_measure;
  35.     int bpm;
  36.     int ticks_per_beat;
  37.     int quantize;
  38. } Song;
  39.  
  40. Song *new_song()
  41. {
  42.     Song *song = malloc(sizeof *song);
  43.     song->measures_per_pattern = 4;
  44.     song->beats_per_measure = 4;
  45.     song->bpm = 125;
  46.     song->ticks_per_beat = 64;
  47.     song->quantize = 128;
  48.    
  49.     int i;
  50.     for(i = 0; i < MAX_SONG_SCENES; i++)
  51.     {
  52.         song->scene_pattern_masks[i] = 0;
  53.     }
  54.    
  55.     for(i = 0; i < MAX_SONG_PATTERNS; i++)
  56.     {
  57.         song->patterns[i].patch = 0;
  58.     }
  59.    
  60.     int a;
  61.     for(i = 0; i < MAX_SONG_PATTERNS; i++)
  62.     {
  63.         song->patterns[a].events_length = 0;
  64.     }
  65.    
  66.     return song;
  67. }
  68.  
  69. typedef enum
  70. {
  71.     MODE_SONG,
  72.     MODE_LOOP,
  73.     MODE_RECORD
  74. } PlayMode;
  75.  
  76. typedef enum
  77. {
  78.     SCREEN_PATTERN,
  79.     SCREEN_SONG,
  80.     SCREEN_PATCH
  81. } Screen;
  82.  
  83. int current_scene = 0;
  84. int playing = 0;
  85. PlayMode current_mode = MODE_LOOP;
  86. Screen current_screen = SCREEN_PATTERN;
  87. Song *song;
  88.  
  89. int pressed_pads = 0;
  90. int first_pressed_pad = 0;
  91.  
  92. void clear_pattern(int pattern)
  93. {
  94.     song->patterns[pattern].events_length = 0;
  95. }
  96.  
  97. void record_event(int pattern, snd_seq_event_t event)
  98. {
  99.     song->patterns[pattern].events[song->patterns[pattern].events_length++] = event;
  100. }
  101.  
  102. int get_mask(int pad)
  103. {
  104.     return 1 << pad;
  105. }
  106.  
  107. void set_pad_pressed_state(int pad, int state)
  108. {
  109.     int mask = get_mask(pad);
  110.     if(state)
  111.     {
  112.         pressed_pads |= mask;
  113.     }
  114.     else
  115.     {
  116.         pressed_pads &= ~mask;
  117.     }
  118. }
  119.  
  120. void set_pad_pressed(int pad)
  121. {
  122.     set_pad_pressed_state(pad, 1);
  123. }
  124.  
  125. void clear_pad_pressed(int pad)
  126. {
  127.     set_pad_pressed_state(pad, 0);
  128. }
  129.  
  130. int get_pad_pressed(int pad)
  131. {
  132.     int mask = get_mask(pad);
  133.     return pressed_pads & mask;
  134. }
  135.  
  136. int get_scene_pattern_mask(int scene)
  137. {
  138.     return song->scene_pattern_masks[scene];
  139. }
  140.  
  141. int get_current_pattern_mask()
  142. {
  143.     return get_scene_pattern_mask(current_scene);
  144. }
  145.  
  146. void set_scene_pattern_mask(int scene, int mask)
  147. {
  148.     song->scene_pattern_masks[scene] = mask;
  149. }
  150.  
  151. void set_current_pattern_mask(int mask)
  152. {
  153.     set_scene_pattern_mask(current_scene, mask);
  154. }
  155.  
  156. void set_pattern_enabled_state(int pattern, int state)
  157. {
  158.     int mask = get_mask(pattern);
  159.     if(state)
  160.     {
  161.         set_current_pattern_mask(get_current_pattern_mask() | mask);
  162.     }
  163.     else
  164.     {
  165.         set_current_pattern_mask(get_current_pattern_mask() & ~mask);
  166.     }
  167. }
  168.  
  169. void toggle_pattern_enabled_state(int pattern)
  170. {
  171.     int mask = get_mask(pattern);
  172.     set_current_pattern_mask(get_current_pattern_mask() ^ mask);
  173. }
  174.  
  175. void set_pattern_enabled(int pattern)
  176. {
  177.     set_pattern_enabled_state(pattern, 1);
  178. }
  179.  
  180. void clear_pattern_enabled(int pattern)
  181. {
  182.     set_pattern_enabled_state(pattern, 0);
  183. }
  184.  
  185. int get_pattern_enabled(int pattern)
  186. {
  187.     int mask = get_mask(pattern);
  188.     return get_current_pattern_mask() & mask;
  189. }
  190.  
  191. void solo_pressed_patterns()
  192. {
  193.     set_current_pattern_mask(pressed_pads);
  194. }
  195.  
  196. void erase_pressed_patterns()
  197. {
  198.     int i;
  199.     for(i = 0; i < MAX_SONG_PATTERNS; i++)
  200.     {
  201.         if(pressed_pads & (1 << i)) clear_pattern(i);
  202.     }
  203. }
  204.  
  205. void set_current_scene(int scene)
  206. {
  207.     while(scene < 0) scene += MAX_SONG_SCENES;
  208.     current_scene = scene % MAX_SONG_SCENES;
  209. }
  210.  
  211. void increment_current_scene()
  212. {
  213.     set_current_scene(current_scene + 1);
  214. }
  215.  
  216. void decrement_current_scene()
  217. {
  218.     set_current_scene(current_scene - 1);
  219. }
  220.  
  221. int get_pattern_patch(int pattern)
  222. {
  223.     return song->patterns[pattern].patch;
  224. }
  225.  
  226. void change_program(int channel, int program);
  227.  
  228. void set_pattern_patch(int pattern, int patch)
  229. {
  230.     while(patch < 0) patch += MAX_SONG_PATCHES;
  231.     song->patterns[pattern].patch = patch % MAX_SONG_PATCHES;
  232.     change_program(pattern, patch);
  233. }
  234.  
  235. void increment_pattern_patch(int pattern)
  236. {
  237.     int patch = get_pattern_patch(pattern);
  238.     set_pattern_patch(pattern, patch + 1);
  239. }
  240.  
  241. void decrement_pattern_patch(int pattern)
  242. {
  243.     int patch = get_pattern_patch(pattern);
  244.     set_pattern_patch(pattern, patch - 1);
  245. }
  246.  
  247. int get_first_selected_pattern()
  248. {
  249.     int i;
  250.     for(i = 0; i < MAX_SONG_PATTERNS; i++)
  251.     {
  252.         if(pressed_pads & (1 << i)) return i;
  253.     }
  254.     return -1;
  255. }
  256.  
  257. void increment_first_selected_patch()
  258. {
  259.     increment_pattern_patch(get_first_selected_pattern());
  260. }
  261.  
  262. void decrement_first_selected_patch()
  263. {
  264.     decrement_pattern_patch(get_first_selected_pattern());
  265. }
  266.  
  267. int get_first_selected_patch()
  268. {
  269.     return get_pattern_patch(get_first_selected_pattern());
  270. }
  271.  
  272. int set_selected_patterns_patch(int patch)
  273. {
  274.     int i;
  275.     for(i = 0; i < MAX_SONG_PATTERNS; i++)
  276.     {
  277.         if(pressed_pads & (1 << i)) set_pattern_patch(i, patch);
  278.     }
  279. }
  280.  
  281. void queue_queue();
  282. void clear_queue();
  283. snd_seq_tick_time_t get_tick();
  284.  
  285. snd_seq_tick_time_t tick = 0;
  286.  
  287. int toggle_playing() // make all these functions cleaner and just simply return ints
  288. {
  289.     playing = !playing;
  290.     clear_queue();
  291.     if(playing)
  292.     {
  293.         tick = get_tick();
  294.         queue_queue();
  295.     }
  296.     return playing;
  297. }
  298.  
  299. int toggle_mode()
  300. {
  301.     switch(current_mode)
  302.     {
  303.         case MODE_LOOP:
  304.             current_mode = MODE_RECORD;
  305.             break;
  306.         case MODE_RECORD:
  307.             current_mode = MODE_SONG;
  308.             break;
  309.         case MODE_SONG:
  310.             current_mode = MODE_LOOP;
  311.             break;
  312.     }
  313.     return current_mode;
  314. }
  315.  
  316. snd_seq_t *seq_handle;
  317. int launch_key_in_port_1_id;
  318. int launch_key_in_port_2_id;
  319. int midi_out_port_id;
  320. int launch_key_out_port_2_id;
  321.  
  322. int queue_id;
  323.  
  324. void pulse_metronome(snd_seq_tick_time_t tick, int color, int sound, int percussion_note);
  325. int new_led_color(int red, int green);
  326.  
  327. snd_seq_tick_time_t next_tick;
  328.  
  329. void queue_queue()
  330. {
  331.     snd_seq_tick_time_t end_tick = song->ticks_per_beat;
  332.     end_tick *= song->beats_per_measure;
  333.     end_tick *= song->measures_per_pattern;
  334.    
  335.     next_tick = tick + end_tick;
  336.    
  337.     snd_seq_event_t event;
  338.    
  339.     snd_seq_ev_clear(&event);
  340.     event.type = SND_SEQ_EVENT_ECHO;
  341.     snd_seq_ev_schedule_tick(&event, queue_id,  0, next_tick);
  342.     snd_seq_ev_set_dest(&event, snd_seq_client_id(seq_handle), launch_key_in_port_1_id);
  343.     snd_seq_event_output_direct(seq_handle, &event);
  344.    
  345.     int mask = get_current_pattern_mask();
  346.    
  347.     int count = 0;
  348.     int i;
  349.     for(i = 0; i < MAX_SONG_PATTERNS; i++)
  350.     {
  351.         if(mask & (1 << i))
  352.         {
  353.             int note_on_events_tick[128];
  354.             int note_on_events_quantized[128];
  355.             int a;
  356.             for(a = 0; a < 128; a++)
  357.             {
  358.                 note_on_events_tick[a] = -1;
  359.             }
  360.             for(a = 0; a < song->patterns[i].events_length; a++)
  361.             {
  362.                 count++;
  363.                 event = song->patterns[i].events[a];
  364.                 snd_seq_tick_time_t dt = event.time.tick;
  365.                 if(event.type == SND_SEQ_EVENT_NOTEON)
  366.                 {
  367.                     note_on_events_tick[event.data.note.note] = dt;
  368.                     int q = song->quantize;
  369.                     q = 1 << q;
  370.                     dt += q / 2;
  371.                     dt /= q;
  372.                     dt *= q;
  373.                     note_on_events_quantized[event.data.note.note] = dt;
  374.                 }
  375.                 else if(event.type == SND_SEQ_EVENT_NOTEOFF)
  376.                 {
  377.                     if(note_on_events_tick[event.data.note.note] != -1)
  378.                     {
  379.                         int length = dt - note_on_events_tick[event.data.note.note];
  380.                         dt = note_on_events_quantized[event.data.note.note] + length;
  381.                         note_on_events_tick[event.data.note.note] = -1;
  382.                     }
  383.                 }
  384.                 snd_seq_ev_schedule_tick(&event, queue_id,  0, tick + dt);
  385.                 snd_seq_ev_set_source(&event, midi_out_port_id);
  386.                 snd_seq_ev_set_subs(&event);
  387.                 snd_seq_event_output_direct(seq_handle, &event);
  388.             }
  389.             change_program(i, song->patterns[i].patch);
  390.         }
  391.     }
  392.    
  393.     for(i = 0; i < song->measures_per_pattern; i++)
  394.     {
  395.         int a;
  396.         for(a = 0; a < song->beats_per_measure; a++)
  397.         {
  398.             int note;
  399.             if(i == 0 && a == 0)
  400.             {
  401.                 note = 75;
  402.             }
  403.             else if(a == 0)
  404.             {
  405.                 note = 76;
  406.             }
  407.             else
  408.             {
  409.                 note = 77;
  410.             }
  411.             int beat = a + i * song->beats_per_measure;
  412.             pulse_metronome(tick + beat * song->ticks_per_beat, a == 0 ? 0 : (i == song->measures_per_pattern - 1 ? 2 : 1), count == 0, note);
  413.         }
  414.     }
  415. }
  416.  
  417. snd_seq_tick_time_t get_tick()
  418. {
  419.   snd_seq_queue_status_t *status;
  420.   snd_seq_tick_time_t current_tick;
  421.  
  422.   snd_seq_queue_status_malloc(&status);
  423.   snd_seq_get_queue_status(seq_handle, queue_id, status);
  424.   current_tick = snd_seq_queue_status_get_tick_time(status);
  425.   snd_seq_queue_status_free(status);
  426.  
  427.   return current_tick;
  428. }
  429.  
  430. void set_tempo(int bpm, int ppq)
  431. {
  432.   snd_seq_queue_tempo_t *queue_tempo;
  433.  
  434.   snd_seq_queue_tempo_malloc(&queue_tempo);
  435.   int tempo = (int)(6e7 / ((double)bpm * (double)ppq) * (double)ppq);
  436.   snd_seq_queue_tempo_set_tempo(queue_tempo, tempo);
  437.   snd_seq_queue_tempo_set_ppq(queue_tempo, ppq);
  438.   snd_seq_set_queue_tempo(seq_handle, queue_id, queue_tempo);
  439.   snd_seq_queue_tempo_free(queue_tempo);
  440. }
  441.  
  442. void change_tempo(int bpm)
  443. {
  444.     song->bpm = bpm;
  445.     set_tempo(song->bpm, song->ticks_per_beat);
  446. }
  447.  
  448. int new_queue()
  449. {
  450.   int id = snd_seq_alloc_queue(seq_handle);
  451.   snd_seq_set_client_pool_output(seq_handle, MAX_QUEUE_SIZE);
  452.   return id;
  453. }
  454.  
  455. void init_queue()
  456. {
  457.     queue_id = new_queue();
  458.     set_tempo(song->bpm, song->ticks_per_beat);
  459.     snd_seq_start_queue(seq_handle, queue_id, NULL);
  460.     snd_seq_drain_output(seq_handle);
  461. }
  462.  
  463. void clear_queue()
  464. {
  465.   snd_seq_remove_events_t *remove_ev;
  466.  
  467.   snd_seq_remove_events_malloc(&remove_ev);
  468.   snd_seq_remove_events_set_queue(remove_ev, queue_id);
  469.   snd_seq_remove_events_set_condition(remove_ev, SND_SEQ_REMOVE_OUTPUT | SND_SEQ_REMOVE_IGNORE_OFF);
  470.   snd_seq_remove_events(seq_handle, remove_ev);
  471.   snd_seq_remove_events_free(remove_ev);
  472. }
  473.  
  474. snd_seq_t *open_client()
  475. {
  476.     snd_seq_t *handle;
  477.     if(snd_seq_open(&handle, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0)
  478.     {
  479.         fprintf(stderr, "Error opening ALSA sequencer.\n");
  480.         return -1;
  481.     }
  482.     snd_seq_set_client_name(handle, ALSA_CLIENT_NAME);
  483.     return handle;
  484. }
  485.  
  486. int new_port(snd_seq_t *handle, char *name, int flags)
  487. {
  488.     int id = snd_seq_create_simple_port(handle, name, flags, SND_SEQ_PORT_TYPE_APPLICATION);
  489.     if(id < 0)
  490.     {
  491.         fprintf(stderr, "Error creating sequencer port.\n");
  492.         return -1;
  493.     }
  494.     return id;
  495. }
  496.  
  497. int new_in_port(snd_seq_t *handle, char *name)
  498. {
  499.     return new_port(handle, name, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE);
  500. }
  501.  
  502. int new_out_port(snd_seq_t *handle, char *name)
  503. {
  504.     return new_port(handle, name, SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ);
  505. }
  506.  
  507. int init_alsa()
  508. {
  509.     if((seq_handle = open_client()) < 0) return -1;
  510.     if((launch_key_in_port_1_id = new_in_port(seq_handle, "LaunchKey MIDI 1")) < 0) return -1;
  511.     if((launch_key_in_port_2_id = new_in_port(seq_handle, "LaunchKey MIDI 2")) < 0) return -1;
  512.     if((midi_out_port_id = new_out_port(seq_handle, "MIDI Out")) < 0) return -1;
  513.     if((launch_key_out_port_2_id = new_out_port(seq_handle, "LaunchKey MIDI 2")) < 0) return -1;
  514.     return 0;
  515. }
  516.  
  517. void change_program(int channel, int program)
  518. {
  519.     snd_seq_event_t event;
  520.     snd_seq_ev_clear(&event);
  521.     snd_seq_ev_set_pgmchange(&event, channel, program);
  522.     snd_seq_ev_set_subs(&event);
  523.     snd_seq_ev_set_source(&event, midi_out_port_id);
  524.     snd_seq_ev_set_direct(&event);
  525.     snd_seq_event_output_direct(seq_handle, &event);
  526. }
  527.  
  528. int control_note_queue = 0;
  529.  
  530. void play_note(int note, int velocity, int channel, int ticks, int tick)
  531. {
  532.     snd_seq_event_t event;
  533.     snd_seq_ev_clear(&event);
  534.     snd_seq_ev_set_note(&event, channel, note, velocity, ticks);
  535.     snd_seq_ev_set_subs(&event);
  536.     snd_seq_ev_set_source(&event, midi_out_port_id);
  537.     snd_seq_ev_schedule_tick(&event, queue_id,  0, tick);
  538.     snd_seq_event_output_direct(seq_handle, &event);
  539. }
  540.  
  541. void send_control_noteon_with_velocity(int note, int velocity)
  542. {
  543.     snd_seq_event_t event;
  544.     snd_seq_ev_clear(&event);
  545.     snd_seq_ev_set_noteon(&event, 0, note, velocity);
  546.     snd_seq_ev_set_subs(&event);
  547.     snd_seq_ev_set_source(&event, launch_key_out_port_2_id);
  548.     if(control_note_queue)
  549.     {
  550.         snd_seq_ev_schedule_tick(&event, queue_id,  0, control_note_queue);
  551.         control_note_queue = 0;
  552.     }
  553.     else
  554.     {
  555.         snd_seq_ev_set_direct(&event);
  556.     }
  557.     snd_seq_event_output_direct(seq_handle, &event);
  558. }
  559.  
  560. void send_control_noteon(int note)
  561. {
  562.     send_control_noteon_with_velocity(note, 127);
  563. }
  564.  
  565. void send_control_noteoff(int note)
  566. {
  567.     snd_seq_event_t event;
  568.     snd_seq_ev_clear(&event);
  569.     snd_seq_ev_set_noteoff(&event, 0, note, 0);
  570.     snd_seq_ev_set_subs(&event);
  571.     snd_seq_ev_set_direct(&event);
  572.     snd_seq_ev_set_source(&event, launch_key_out_port_2_id);
  573.     snd_seq_event_output_direct(seq_handle, &event);
  574. }
  575.  
  576. void enable_in_control()
  577. {
  578.     send_control_noteon(12);
  579. }
  580.  
  581. void disable_in_control()
  582. {
  583.     send_control_noteon_with_velocity(12, 0);
  584. }
  585.  
  586. void show_in_control()
  587. {
  588.     send_control_noteon(10);
  589. }
  590.  
  591. void hide_in_control()
  592. {
  593.     send_control_noteon_with_velocity(10, 0);
  594. }
  595.  
  596. int led_id_to_pad_id(led_id)
  597. {
  598.     switch(led_id)
  599.     {
  600.         case 0:
  601.             return 96;
  602.         case 1:
  603.             return 97;
  604.         case 2:
  605.             return 98;
  606.         case 3:
  607.             return 99;
  608.         case 4:
  609.             return 100;
  610.         case 5:
  611.             return 101;
  612.         case 6:
  613.             return 102;
  614.         case 7:
  615.             return 103;
  616.         case 8:
  617.             return 112;
  618.         case 9:
  619.             return 113;
  620.         case 10:
  621.             return 114;
  622.         case 11:
  623.             return 115;
  624.         case 12:
  625.             return 116;
  626.         case 13:
  627.             return 117;
  628.         case 14:
  629.             return 118;
  630.         case 15:
  631.             return 119;
  632.         case 16:
  633.             return 104;
  634.         case 17:
  635.             return 120;
  636.         default:
  637.             return 0;
  638.     }
  639. }
  640.  
  641. int new_led_color(int red, int green)
  642. {
  643.     return red + (green << 4);
  644. }
  645.  
  646. void set_led(int led_id, int color)
  647. {
  648.     int pad_id = led_id_to_pad_id(led_id);
  649.     send_control_noteon_with_velocity(pad_id, color);
  650. }
  651.  
  652. int get_led_id_by_xy(int x, int y)
  653. {
  654.     if(x < 0 || y < 0 || x > 8 || y > 1) return;
  655.     if(x == 8)
  656.     {
  657.         return y ? 17 : 16;
  658.     }
  659.     else
  660.     {
  661.         return x + y * 8;
  662.     }
  663. }
  664.  
  665. void set_led_xy(int x, int y, int color)
  666. {
  667.     int led_id = get_led_id_by_xy(x, y);
  668.     set_led(led_id, color);
  669. }
  670.  
  671. void set_led_rect(int x, int y, int w, int h, int color)
  672. {
  673.     int ox = x;
  674.     int oy = y;
  675.     int mx = x+w;
  676.     int my = y+h;
  677.     for(x=ox; x<mx; x++)
  678.     {
  679.         for(y=oy; y<my; y++)
  680.         {
  681.             set_led_xy(x, y, color);
  682.         }
  683.     }
  684. }
  685.  
  686. void set_led_row(int y, int color)
  687. {
  688.     set_led_rect(0, y, 9, 1, color);
  689. }
  690.  
  691. void set_led_column(int x, int color)
  692. {
  693.     set_led_rect(x, 0, 1, 2, color);
  694. }
  695.  
  696. void led_fill(int color)
  697. {
  698.     set_led_rect(0, 0, 9, 2, color);
  699. }
  700.  
  701. void led_clear()
  702. {
  703.     led_fill(0);
  704. }
  705.  
  706. void led_test()
  707. {
  708.     set_led_column(0, new_led_color(2, 0));
  709.     set_led_column(1, new_led_color(3, 0));
  710.     set_led_column(2, new_led_color(3, 1));
  711.     set_led_column(3, new_led_color(3, 2));
  712.     set_led_column(4, new_led_color(3, 3));
  713.     set_led_column(5, new_led_color(2, 3));
  714.     set_led_column(6, new_led_color(1, 3));
  715.     set_led_column(7, new_led_color(0, 3));
  716.     set_led_column(8, new_led_color(0, 2));
  717. }
  718.  
  719. void led_test_2()
  720. {
  721.     set_led_column(8, new_led_color(2, 0));
  722.     set_led_column(7, new_led_color(3, 0));
  723.     set_led_column(6, new_led_color(3, 1));
  724.     set_led_column(5, new_led_color(3, 2));
  725.     set_led_column(4, new_led_color(3, 3));
  726.     set_led_column(3, new_led_color(2, 3));
  727.     set_led_column(2, new_led_color(1, 3));
  728.     set_led_column(1, new_led_color(0, 3));
  729.     set_led_column(0, new_led_color(0, 2));
  730. }
  731.  
  732. void led_test_3()
  733. {
  734.     set_led_row(0, new_led_color(3, 0));
  735.     set_led_row(1, new_led_color(0, 3));
  736. }
  737.  
  738. void led_test_4()
  739. {
  740.     set_led_xy(0, 0, new_led_color(0, 0));
  741.     set_led_xy(1, 0, new_led_color(0, 1));
  742.     set_led_xy(2, 0, new_led_color(0, 2));
  743.     set_led_xy(3, 0, new_led_color(0, 3));
  744.     set_led_xy(0, 1, new_led_color(0, 0));
  745.     set_led_xy(1, 1, new_led_color(1, 1));
  746.     set_led_xy(2, 1, new_led_color(2, 2));
  747.     set_led_xy(3, 1, new_led_color(3, 3));
  748.     set_led_xy(4, 0, new_led_color(0, 0));
  749.     set_led_xy(5, 0, new_led_color(1, 0));
  750.     set_led_xy(6, 0, new_led_color(2, 0));
  751.     set_led_xy(7, 0, new_led_color(3, 0));
  752.     set_led_xy(4, 1, new_led_color(4, 1));
  753.     set_led_xy(5, 1, new_led_color(1, 4));
  754.     set_led_xy(6, 1, new_led_color(3, 1));
  755.     set_led_xy(7, 1, new_led_color(1, 3));
  756.     set_led_xy(8, 0, new_led_color(3, 2));
  757.     set_led_xy(8, 1, new_led_color(2, 3));
  758. }
  759.  
  760. void pulse_metronome(snd_seq_tick_time_t tick, int color, int sound, int percussion_note)
  761. {
  762.     int i = 0;
  763.     int brightness = 4;
  764.     while(brightness)
  765.     {
  766.         brightness--;
  767.         int c;
  768.         if(color == 0)
  769.         {
  770.             c = new_led_color(brightness, 0);
  771.         }
  772.         else if(color == 1)
  773.         {
  774.             c = new_led_color(0, brightness);
  775.         }
  776.         else if(color == 2)
  777.         {
  778.             c = new_led_color(brightness, brightness);
  779.         }
  780.         control_note_queue = tick + i * (song->ticks_per_beat / METRONOME_PULSE_FRAMES_PER_BEAT);
  781.         set_led_xy(8, 0, c);
  782.         i++;
  783.     }
  784.     if(sound) play_note(percussion_note, 63, 9, 10, tick);
  785. }
  786.  
  787. int get_pad_x(int pad)
  788. {
  789.     if(pad < 16)
  790.     {
  791.         return pad % 8;
  792.     }
  793.     else
  794.     {
  795.         return 8;
  796.     }
  797. }
  798.  
  799. int get_pad_y(int pad)
  800. {
  801.     if(pad < 16)
  802.     {
  803.         return pad / 8;
  804.     }
  805.     else if(pad == 16)
  806.     {
  807.         return 0;
  808.     }
  809.     else if(pad == 17)
  810.     {
  811.         return 1;
  812.     }
  813. }
  814.  
  815. int set_digit(number, base, digit, replacement_value)
  816. {
  817.     int i;
  818.     for(i = 0; i < digit; i++)
  819.     {
  820.         replacement_value *= base;
  821.     }
  822.    
  823.     int place_holder_value = number;
  824.     for(i = 0; i < digit; i++)
  825.     {
  826.         place_holder_value /= base;
  827.     }
  828.     place_holder_value %= base;
  829.     for(i = 0; i < digit; i++)
  830.     {
  831.         place_holder_value *= base;
  832.     }
  833.    
  834.     number -= place_holder_value;
  835.     number += replacement_value;
  836.     return number;
  837. }
  838.  
  839. void display_number(number)
  840. {
  841.     led_clear();
  842.    
  843.     int digit_0 = number % 8;
  844.     number /= 8;
  845.     int digit_1 = number % 8;
  846.     number /= 8;
  847.     int digit_2 = number % 2;
  848.    
  849.     set_led_xy(digit_0, 0, new_led_color(3, 0));
  850.     set_led_xy(digit_1, 1, new_led_color(3, 3));
  851.     set_led_xy(8, digit_2, new_led_color(1, 3));
  852. }
  853.  
  854. int replace_number_screen_value(num)
  855. {
  856.     if(current_screen == SCREEN_SONG)
  857.     {
  858.         current_scene = num;
  859.     }
  860.     else if(current_screen == SCREEN_PATCH)
  861.     {
  862.         set_selected_patterns_patch(num);
  863.     }
  864.     display_number(num);
  865. }
  866.  
  867. int get_number_screen_value()
  868. {
  869.     int num;
  870.     if(current_screen == SCREEN_SONG)
  871.     {
  872.         num = current_scene;
  873.     }
  874.     else if(current_screen == SCREEN_PATCH)
  875.     {
  876.         num = get_first_selected_patch();
  877.     }
  878.     return num;
  879. }
  880.  
  881. void pattern_screen_update_play_button()
  882. {
  883.     if(playing)
  884.     {
  885.         set_led(16, new_led_color(0, 3));
  886.     }
  887.     else
  888.     {
  889.         set_led(16, new_led_color(0, 0));
  890.     }
  891. }
  892.  
  893. void pattern_screen_update_mode_button()
  894. {
  895.     switch(current_mode)
  896.     {
  897.         case MODE_SONG:
  898.             set_led(17, new_led_color(0, 0));
  899.             break;
  900.         case MODE_LOOP:
  901.             set_led(17, new_led_color(0, 3));
  902.             break;
  903.         case MODE_RECORD:
  904.             set_led(17, new_led_color(3, 0));
  905.             break;
  906.     }
  907. }
  908.  
  909. void pattern_screen_update_pad(int pad)
  910. {
  911.     if(pad < 16)
  912.     {
  913.         if(get_pad_pressed(pad))
  914.         {
  915.             set_led(pad, new_led_color(3, 0));
  916.         }
  917.         else
  918.         {
  919.             if(get_pattern_enabled(pad))
  920.             {
  921.                 if(song->patterns[pad].events_length)
  922.                 {
  923.                     set_led(pad, new_led_color(3, 3));
  924.                 }
  925.                 else
  926.                 {
  927.                     set_led(pad, new_led_color(0, 3));
  928.                 }
  929.             }
  930.             else
  931.             {
  932.                 if(song->patterns[pad].events_length)
  933.                 {
  934.                     set_led(pad, new_led_color(0, 0));
  935.                 }
  936.                 else
  937.                 {
  938.                     set_led(pad, new_led_color(0, 0));
  939.                 }
  940.             }
  941.         }
  942.     }
  943.     else if(pad == 16)
  944.     {
  945.         pattern_screen_update_play_button();
  946.     }
  947.     else if(pad == 17)
  948.     {
  949.         pattern_screen_update_mode_button();
  950.     }
  951. }
  952.  
  953. void pattern_screen_update_pads()
  954. {
  955.     int i;
  956.     for(i = 0; i < 18; i++)
  957.     {
  958.         pattern_screen_update_pad(i);
  959.     }
  960. }
  961.  
  962. void pattern_screen()
  963. {
  964.     current_screen = SCREEN_PATTERN;
  965.     pattern_screen_update_pads();
  966. }
  967.  
  968. void patch_screen()
  969. {
  970.     current_screen = SCREEN_PATCH;
  971.     first_pressed_pad = get_first_selected_pattern();
  972.     display_number(get_first_selected_patch());
  973. }
  974.  
  975. void song_screen()
  976. {
  977.     current_screen = SCREEN_SONG;
  978.     display_number(current_scene);
  979. }
  980.  
  981. void init_screen()
  982. {
  983.     enable_in_control();
  984.     pattern_screen();
  985. }
  986.  
  987. void play_press()
  988. {
  989.     switch(current_screen)
  990.     {
  991.         case SCREEN_PATTERN:
  992.             if(pressed_pads)
  993.             {
  994.                 solo_pressed_patterns();
  995.                 pressed_pads = 0;
  996.                 pattern_screen_update_pads();
  997.             }
  998.             else
  999.             {
  1000.                 toggle_playing();
  1001.                 pattern_screen_update_play_button();
  1002.             }
  1003.             break;
  1004.            
  1005.         case SCREEN_SONG:
  1006.         case SCREEN_PATCH: ;
  1007.             int num = get_number_screen_value();
  1008.             num = set_digit(num, 8, 2, 0);
  1009.             replace_number_screen_value(num);
  1010.            
  1011.             break;
  1012.     }
  1013. }
  1014.  
  1015. void play_release()
  1016. {
  1017.    
  1018. }
  1019.  
  1020. void mode_press()
  1021. {
  1022.     switch(current_screen)
  1023.     {
  1024.         case SCREEN_PATTERN:
  1025.             if(pressed_pads)
  1026.             {
  1027.                 erase_pressed_patterns();
  1028.                 pressed_pads = 0;
  1029.                 pattern_screen_update_pads();
  1030.             }
  1031.             else
  1032.             {
  1033.                 toggle_mode();
  1034.                 pattern_screen_update_mode_button();
  1035.             }
  1036.             break;
  1037.            
  1038.         case SCREEN_SONG:
  1039.         case SCREEN_PATCH: ;
  1040.             int num = get_number_screen_value();
  1041.             num = set_digit(num, 8, 2, 1);
  1042.             replace_number_screen_value(num);
  1043.             break;
  1044.     }
  1045. }
  1046.  
  1047. void mode_release()
  1048. {
  1049.    
  1050. }
  1051.  
  1052. void pad_press(int pad)
  1053. {
  1054.     switch(current_screen)
  1055.     {
  1056.         case SCREEN_PATTERN:
  1057.             set_pad_pressed(pad);
  1058.             pattern_screen_update_pad(pad);
  1059.             break;
  1060.            
  1061.         case SCREEN_SONG:
  1062.         case SCREEN_PATCH: ;
  1063.             int x = get_pad_x(pad);
  1064.             int y = get_pad_y(pad);
  1065.            
  1066.             int num = get_number_screen_value();
  1067.             num = set_digit(num, 8, y, x);
  1068.             replace_number_screen_value(num);
  1069.            
  1070.             break;
  1071.     }
  1072. }
  1073.  
  1074. void pad_release(int pad)
  1075. {
  1076.     switch(current_screen)
  1077.     {
  1078.         case SCREEN_PATTERN:
  1079.             if(get_pad_pressed(pad))
  1080.             {
  1081.                 clear_pad_pressed(pad);
  1082.                 toggle_pattern_enabled_state(pad);
  1083.                 pattern_screen_update_pad(pad);
  1084.             }
  1085.             break;
  1086.            
  1087.         case SCREEN_SONG:
  1088.             break;
  1089.            
  1090.         case SCREEN_PATCH: ;
  1091.             if(pad == first_pressed_pad)
  1092.             {
  1093.                 pressed_pads = 0;
  1094.                 pattern_screen();
  1095.             }
  1096.             break;
  1097.     }
  1098. }
  1099.  
  1100. void arrow_presed(int up)
  1101. {
  1102.     switch(current_screen)
  1103.     {
  1104.         case SCREEN_PATTERN:
  1105.             if(pressed_pads)
  1106.             {
  1107.                 patch_screen();
  1108.                 int num = get_number_screen_value();
  1109.                 if(up)
  1110.                 {
  1111.                     num = (num + 1) % MAX_SONG_PATCHES;
  1112.                 }
  1113.                 else
  1114.                 {
  1115.                     num--;
  1116.                     while(num < 0) num += MAX_SONG_PATCHES;
  1117.                 }
  1118.                 replace_number_screen_value(num);
  1119.             }
  1120.             else
  1121.             {
  1122.                 if(up)
  1123.                 {
  1124.                     increment_current_scene();
  1125.                 }
  1126.                 else
  1127.                 {
  1128.                     decrement_current_scene();
  1129.                 }
  1130.                 song_screen();
  1131.             }
  1132.             break;
  1133.            
  1134.         case SCREEN_SONG:
  1135.             break;
  1136.            
  1137.         case SCREEN_PATCH: ;
  1138.             int num = get_number_screen_value();
  1139.             if(up)
  1140.             {
  1141.                 num = (num + 1) % MAX_SONG_PATCHES;
  1142.             }
  1143.             else
  1144.             {
  1145.                 num--;
  1146.                 while(num < 0) num += MAX_SONG_PATCHES;
  1147.             }
  1148.             replace_number_screen_value(num);
  1149.             break;
  1150.     }
  1151. }
  1152.  
  1153. void left()
  1154. {
  1155.     arrow_presed(0);
  1156. }
  1157.  
  1158. void right()
  1159. {
  1160.     arrow_presed(1);
  1161. }
  1162.  
  1163. void up()
  1164. {
  1165.     right();
  1166. }
  1167.  
  1168. void down()
  1169. {
  1170.     left();
  1171. }
  1172.  
  1173. void horizontal_release()
  1174. {
  1175.     switch(current_screen)
  1176.     {
  1177.         case SCREEN_PATTERN:
  1178.         case SCREEN_PATCH:
  1179.             break;
  1180.            
  1181.         case SCREEN_SONG: ;
  1182.             pressed_pads = 0;
  1183.             pattern_screen();
  1184.             break;
  1185.     }
  1186. }
  1187.  
  1188. void vertical_release()
  1189. {
  1190.     horizontal_release();
  1191. }
  1192.  
  1193. void pass_event(snd_seq_event_t *event)
  1194. {
  1195.     snd_seq_ev_set_subs(event);
  1196.     snd_seq_ev_set_direct(event);
  1197.     snd_seq_ev_set_source(event, midi_out_port_id);
  1198.     snd_seq_event_output_direct(seq_handle, event);
  1199.    
  1200.     if(current_mode == MODE_RECORD)
  1201.     {
  1202.         int chan = event->data.note.channel;
  1203.         if(!playing)
  1204.         {
  1205.             toggle_playing();
  1206.             pattern_screen_update_play_button();
  1207.         }
  1208.         snd_seq_event_t e = *event;
  1209.         snd_seq_tick_time_t dt = get_tick() - tick;
  1210.         e.time.tick = dt;
  1211.         record_event(chan, e);
  1212.         if(current_screen == SCREEN_PATTERN)
  1213.         {
  1214.             set_pattern_enabled(chan);
  1215.             pattern_screen_update_pad(chan);
  1216.         }
  1217.     }
  1218. }
  1219.  
  1220. void handle_event(snd_seq_event_t *event)
  1221. {
  1222.     int is_port_1 = event->dest.port == launch_key_in_port_1_id ? 1 : 0;
  1223.     int is_port_2 = event->dest.port == launch_key_in_port_2_id ? 1 : 0;
  1224.    
  1225.     switch(event->type)
  1226.     {
  1227.         case SND_SEQ_EVENT_PORT_SUBSCRIBED:
  1228.         case SND_SEQ_EVENT_PORT_CHANGE:
  1229.         case SND_SEQ_EVENT_CLIENT_START:
  1230.         case SND_SEQ_EVENT_CLIENT_CHANGE:
  1231.             init_screen();
  1232.             break;
  1233.            
  1234.         case SND_SEQ_EVENT_ECHO:
  1235.             if(current_mode == MODE_SONG)
  1236.             {
  1237.                 increment_current_scene();
  1238.                 if(current_screen == SCREEN_PATTERN)
  1239.                 {
  1240.                     pattern_screen_update_pads();
  1241.                 }
  1242.             }
  1243.             tick = next_tick;
  1244.             queue_queue();
  1245.             break;
  1246.            
  1247.         case SND_SEQ_EVENT_NOTEON:
  1248.             if(is_port_2)
  1249.             {
  1250.                 switch(event->data.note.note)
  1251.                 {
  1252.                     case 10:
  1253.                         pattern_screen();
  1254.                         break;
  1255.                        
  1256.                     case 104:
  1257.                         play_press();
  1258.                         break;
  1259.                     case 120:
  1260.                         mode_press();
  1261.                         break;
  1262.                    
  1263.                     case 96:
  1264.                         pad_press(0);
  1265.                         break;
  1266.                     case 97:
  1267.                         pad_press(1);
  1268.                         break;
  1269.                     case 98:
  1270.                         pad_press(2);
  1271.                         break;
  1272.                     case 99:
  1273.                         pad_press(3);
  1274.                         break;
  1275.                     case 100:
  1276.                         pad_press(4);
  1277.                         break;
  1278.                     case 101:
  1279.                         pad_press(5);
  1280.                         break;
  1281.                     case 102:
  1282.                         pad_press(6);
  1283.                         break;
  1284.                     case 103:
  1285.                         pad_press(7);
  1286.                         break;
  1287.                     case 112:
  1288.                         pad_press(8);
  1289.                         break;
  1290.                     case 113:
  1291.                         pad_press(9);
  1292.                         break;
  1293.                     case 114:
  1294.                         pad_press(10);
  1295.                         break;
  1296.                     case 115:
  1297.                         pad_press(11);
  1298.                         break;
  1299.                     case 116:
  1300.                         pad_press(12);
  1301.                         break;
  1302.                     case 117:
  1303.                         pad_press(13);
  1304.                         break;
  1305.                     case 118:
  1306.                         pad_press(14);
  1307.                         break;
  1308.                     case 119:
  1309.                         pad_press(15);
  1310.                         break;
  1311.                 }
  1312.             }
  1313.             else
  1314.             {
  1315.                 pass_event(event);
  1316.             }
  1317.            
  1318.             break;
  1319.            
  1320.         case SND_SEQ_EVENT_NOTEOFF:
  1321.             if(is_port_2)
  1322.             {
  1323.                 switch(event->data.note.note)
  1324.                 {
  1325.                     case 104:
  1326.                         play_release();
  1327.                         break;
  1328.                     case 120:
  1329.                         mode_release();
  1330.                         break;
  1331.                    
  1332.                     case 96:
  1333.                         pad_release(0);
  1334.                         break;
  1335.                     case 97:
  1336.                         pad_release(1);
  1337.                         break;
  1338.                     case 98:
  1339.                         pad_release(2);
  1340.                         break;
  1341.                     case 99:
  1342.                         pad_release(3);
  1343.                         break;
  1344.                     case 100:
  1345.                         pad_release(4);
  1346.                         break;
  1347.                     case 101:
  1348.                         pad_release(5);
  1349.                         break;
  1350.                     case 102:
  1351.                         pad_release(6);
  1352.                         break;
  1353.                     case 103:
  1354.                         pad_release(7);
  1355.                         break;
  1356.                     case 112:
  1357.                         pad_release(8);
  1358.                         break;
  1359.                     case 113:
  1360.                         pad_release(9);
  1361.                         break;
  1362.                     case 114:
  1363.                         pad_release(10);
  1364.                         break;
  1365.                     case 115:
  1366.                         pad_release(11);
  1367.                         break;
  1368.                     case 116:
  1369.                         pad_release(12);
  1370.                         break;
  1371.                     case 117:
  1372.                         pad_release(13);
  1373.                         break;
  1374.                     case 118:
  1375.                         pad_release(14);
  1376.                         break;
  1377.                     case 119:
  1378.                         pad_release(15);
  1379.                         break;
  1380.                 }
  1381.             }
  1382.             else
  1383.             {
  1384.                 pass_event(event);
  1385.             }
  1386.            
  1387.             break;
  1388.        
  1389.         case SND_SEQ_EVENT_CONTROLLER:
  1390.             if(is_port_2)
  1391.             {
  1392.                 switch(event->data.control.param)
  1393.                 {
  1394.                     case 27:
  1395.                         song->quantize = event->data.control.value  / 16;
  1396.                         break;
  1397.                     case 28:
  1398.                         change_tempo(event->data.control.value * 3 / 2 + 32);
  1399.                         break;
  1400.                 }
  1401.                 if(event->data.control.value)
  1402.                 {
  1403.                     switch(event->data.control.param)
  1404.                     {
  1405.                         case 104:
  1406.                             up();
  1407.                             break;
  1408.                         case 105:
  1409.                             down();
  1410.                             break;
  1411.                         case 106:
  1412.                             left();
  1413.                             break;
  1414.                         case 107:
  1415.                             right();
  1416.                             break;
  1417.                     }
  1418.                 }
  1419.                 else
  1420.                 {
  1421.                     switch(event->data.control.param)
  1422.                     {
  1423.                         case 104:
  1424.                         case 105:
  1425.                             vertical_release();
  1426.                             break;
  1427.                         case 106:
  1428.                         case 107:
  1429.                             horizontal_release();
  1430.                             break;
  1431.                     }
  1432.                 }
  1433.             }
  1434.             else
  1435.             {
  1436.                 switch(event->data.control.param)
  1437.                 {
  1438.                     case 104:
  1439.                     case 105:
  1440.                     case 106:
  1441.                     case 107:
  1442.                         init_screen();
  1443.                         break;
  1444.                 }
  1445.                 pass_event(event);
  1446.             }
  1447.            
  1448.             break;
  1449.            
  1450.         case SND_SEQ_EVENT_PITCHBEND:
  1451.             pass_event(event);
  1452.             break;
  1453.     }
  1454. }
  1455.  
  1456. void sigterm_exit(int sig)
  1457. {
  1458.     printf("Cleaning up...\n");
  1459.     sleep(1);
  1460.     snd_seq_stop_queue(seq_handle, queue_id, NULL);
  1461.     snd_seq_free_queue(seq_handle, queue_id);
  1462.     exit(0);
  1463. }
  1464.  
  1465. int main(int argc, char *argv[])
  1466. {
  1467.     if(init_alsa() < 0)
  1468.     {
  1469.         fprintf(stderr, "Error initializing.\n");
  1470.         exit(1);
  1471.     }
  1472.    
  1473.     song = new_song();
  1474.     init_queue();
  1475.    
  1476.     signal(SIGINT, sigterm_exit);
  1477.     signal(SIGTERM, sigterm_exit);
  1478.      
  1479.     int l1;
  1480.     int npfd = snd_seq_poll_descriptors_count(seq_handle, POLLIN);
  1481.     struct pollfd *pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd));
  1482.     snd_seq_poll_descriptors(seq_handle, pfd, npfd, POLLIN);
  1483.     snd_seq_event_t *event;
  1484.    
  1485.     while(1)
  1486.     {
  1487.         if(poll(pfd, npfd, 100000) > 0)
  1488.         {
  1489.             for(l1 = 0; l1 < npfd; l1++)
  1490.             {
  1491.                 if(pfd[l1].revents > 0)
  1492.                 {
  1493.                     do
  1494.                     {
  1495.                         snd_seq_event_input(seq_handle, &event);
  1496.                         handle_event(event);
  1497.                         snd_seq_free_event(event);
  1498.                     } while(snd_seq_event_input_pending(seq_handle, 0) > 0);
  1499.                 }
  1500.             }
  1501.         }
  1502.     }
  1503.     return 0;
  1504. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement