?? mm_cb.c
字號:
/* * This file contains the callback routines for MusicMachine */#include <assert.h>#include "forms.h"#include "mm.h"#include "soundit.h"#include "mm_util.h"/* array containing notes for all channels */int notes[NUM_CHANNELS][NUM_PAGES*NUM_CHANNELS];/* current position in notes array for each channel */int pos[NUM_CHANNELS];/* flags indicating if a channel is stopped */int stopped[NUM_CHANNELS];/* main window file menu */void file_menu_cbk(FL_OBJECT *ob, long data){ const char *filename; switch (fl_get_menu(ob)) { case 1: /* load */ filename = fl_show_fselector("Load from file:", "", "", ""); if (filename != 0) load_sample_file(filename); break; case 2: /* save */ filename = fl_show_fselector("Save to file:", "", "", ""); if (filename != 0) { save_sample_file(filename); fl_invalidate_fselector_cache(); } break; case 3: /* new */ if (fl_show_question("Clear the current patterns?", 0, 0)) { clear_samples(); update_bitmaps(); } break; case 4: /* about */ fl_show_form(about_window, FL_PLACE_CENTER, FL_FULLBORDER, "About"); break; case 5: /* quit */ if (fl_show_question("Do you want to quit?", 0, 0)) { Snd_restore(); exit(0); } break; default: assert(0); /* should never happen */ }}/* main window edit menu */void edit_menu_cbk(FL_OBJECT *ob, long data){ /* only menu item is "options" */ fl_show_form(sample_window, FL_PLACE_CENTER, FL_FULLBORDER, "Options");}/* play button */void play_button_cbk(FL_OBJECT *ob, long data){ int i; /* reset position to the start for all channels */ for (i = 0 ; i < NUM_CHANNELS ; i++) { pos[i] = 0; stopped[i] = 0; } /* start timer object by giving it a very small non-zero value */ fl_set_timer(timer, 0.001);}/* tempo slider */void tempo_slider_cbk(FL_OBJECT *ob, long data){ /* nothing to do */}/* used by callbacks for rhythm buttons for all channels */void channel_callback(FL_OBJECT *ob, long data, int channel){ /* get current value */ int i = (int) data + SAMPLES_PER_PAGE * (int) fl_get_counter_value(page); /* see which mouse button was pushed */ switch (fl_get_button_numb(ob)) { case 1: /* increment value */ notes[channel][i]++; break; case 2: /* note value becomes a rest */ notes[channel][i] = REST; break; case 3: /* decrement value */ notes[channel][i]--; break; default: assert(0); /* should never happen */ } /* wrap around when first or last value reached */ if (notes[channel][i] == STOP-1) notes[channel][i] = 16; if (notes[channel][i] > NUM_SAMPLES) notes[channel][i] = STOP; update_bitmap(ob, notes[channel][i]);}/* rhythm buttons for channel 0 */void channel_0_cbk(FL_OBJECT *ob, long data){ channel_callback(ob, data, 0);}/* rhythm buttons for channel 1 */void channel_1_cbk(FL_OBJECT *ob, long data){ channel_callback(ob, data, 1);}/* rhythm buttons for channel 2 */void channel_2_cbk(FL_OBJECT *ob, long data){ channel_callback(ob, data, 2);}/* rhythm buttons for channel 3 */void channel_3_cbk(FL_OBJECT *ob, long data){ channel_callback(ob, data, 3);}/* rhythm buttons for channel 4 */void channel_4_cbk(FL_OBJECT *ob, long data){ channel_callback(ob, data, 4);}/* rhythm buttons for channel 5 */void channel_5_cbk(FL_OBJECT *ob, long data){ channel_callback(ob, data, 5);}/* rhythm buttons for channel 6 */void channel_6_cbk(FL_OBJECT *ob, long data){ channel_callback(ob, data, 6);}/* rhythm buttons for channel 7 */void channel_7_cbk(FL_OBJECT *ob, long data){ channel_callback(ob, data, 7);}/* page button */void page_button_cbk(FL_OBJECT *ob, long data){ /* the button itself updates the page number, we just need to update the display */ update_bitmaps();}/* stop button */void stop_button_cbk(FL_OBJECT *ob, long data){ /* stop timer by giving it a zero value */ fl_set_timer(timer, 0);}/* callback for timer */void timer_cbk(FL_OBJECT *ob, long data){ int ch; for (ch = 0 ; ch < NUM_CHANNELS ; ch++) /* play sound for this channel if it is a note and channel has not been stopped */ if (notes[ch][pos[ch]] > 0 && notes[ch][pos[ch]] <= NUM_SAMPLES && !stopped[ch]) Snd_effect(notes[ch][pos[ch]] - 1, ch); /* advance to next position */ for (ch = 0 ; ch < NUM_CHANNELS ; ch++) { pos[ch]++; /* wrap around at end */ if (pos[ch] >= NUM_PAGES*SAMPLES_PER_PAGE) pos[ch] = 0; /* check for loop back to start */ if (notes[ch][pos[ch]] == LOOP) pos[ch] = 0; /* check for stop */ if (notes[ch][pos[ch]] == STOP) stopped[ch] = 1; } /* set timer for next time, tempo is in beats per minute */ fl_set_timer(ob, 60.0 / fl_get_slider_value(tempo));}/* sample file entry */void sample_file_cbk(FL_OBJECT *ob, long data){ char file[256]; char msg[256]; /* make sure file exists */ strcpy(file, fl_get_input(sample_dir)); strcat(file, "/"); strcat(file, fl_get_input(ob)); if (!file_exists(file)) { sprintf(msg, "Sample file \"%s\" does not exist.", file); fl_show_alert("Warning:", msg, "Enter a valid sample file name and try again.", 0); }}/* apply button */void samples_apply_cbk(FL_OBJECT *ob, long data){ /* reload new set of samples and parameters */ init_samples();}/* options dismiss button */void samples_dismiss_cbk(FL_OBJECT *ob, long data){ /* make window go away */ fl_hide_form(sample_window);}/* audio device entry field */void audio_device_cbk(FL_OBJECT *ob, long data){ char msg[256]; const char *file = fl_get_input(ob); if (!file_exists(file)) { sprintf(msg, "Sample device \"%s\" does not exist.", file); fl_show_alert("Warning:", msg, "Enter a valid sample device file name and try again.", 0); }}/* sampling rate entry field */void sampling_rate_cbk(FL_OBJECT *ob, long data){ /* do a simple range check */ int rate = atoi(fl_get_input(sampling_rate)); if (rate < 4000 || rate > 45000) fl_show_alert("Warning:", "Invalid sample rate.", "Enter a decimal number between 4000 and 45000", 0);}/* buttons next to each sample file */void test_sample_cbk(FL_OBJECT *ob, long data){ /* play the sample passed to callback */ Snd_effect(data, data % NUM_CHANNELS);}/* callback for sample directory entry field */void sample_dir_cbk(FL_OBJECT *ob, long data){ const char *file = fl_get_input(ob); char msg[256]; if (!file_exists(file)) { sprintf(msg, "Sample directory \"%s\" does not exist.", file); fl_show_alert("Warning:", msg, "Enter a valid directory name and try again.", 0); }}/* about dismiss button */void about_dismiss_cbk(FL_OBJECT *obj, long data){ /* make window go away */ fl_hide_form(about_window);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -