📄 instrum.c
字号:
}/*! Release ToneBank[128 + MAP_BANK_COUNT] */static void free_tone_bank_list(ToneBank *tb[]){ int i, j; ToneBank *bank; for (i = 0; i < 128 + map_bank_counter; i++) { bank = tb[i]; if (!bank) continue; for (j = 0; j < 128; j++) free_tone_bank_element(&bank->tone[j]); if (i > 0) { free(bank); tb[i] = NULL; } }}/*! Release tonebank and drumset */void free_tone_bank(void){ free_tone_bank_list(tonebank); free_tone_bank_list(drumset);}/*! Release ToneBankElement. */void free_tone_bank_element(ToneBankElement *elm){ elm->instype = 0; if (elm->name) free(elm->name); elm->name = NULL; if (elm->tune) free(elm->tune); elm->tune = NULL, elm->tunenum = 0; if (elm->envratenum) free_ptr_list(elm->envrate, elm->envratenum); elm->envrate = NULL, elm->envratenum = 0; if (elm->envofsnum) free_ptr_list(elm->envofs, elm->envofsnum); elm->envofs = NULL, elm->envofsnum = 0; if (elm->tremnum) free_ptr_list(elm->trem, elm->tremnum); elm->trem = NULL, elm->tremnum = 0; if (elm->vibnum) free_ptr_list(elm->vib, elm->vibnum); elm->vib = NULL, elm->vibnum = 0; if (elm->sclnote) free(elm->sclnote); elm->sclnote = NULL, elm->sclnotenum = 0; if (elm->scltune) free(elm->scltune); elm->scltune = NULL, elm->scltunenum = 0; if (elm->comment) free(elm->comment); elm->comment = NULL; if (elm->modenvratenum) free_ptr_list(elm->modenvrate, elm->modenvratenum); elm->modenvrate = NULL, elm->modenvratenum = 0; if (elm->modenvofsnum) free_ptr_list(elm->modenvofs, elm->modenvofsnum); elm->modenvofs = NULL, elm->modenvofsnum = 0; if (elm->envkeyfnum) free_ptr_list(elm->envkeyf, elm->envkeyfnum); elm->envkeyf = NULL, elm->envkeyfnum = 0; if (elm->envvelfnum) free_ptr_list(elm->envvelf, elm->envvelfnum); elm->envvelf = NULL, elm->envvelfnum = 0; if (elm->modenvkeyfnum) free_ptr_list(elm->modenvkeyf, elm->modenvkeyfnum); elm->modenvkeyf = NULL, elm->modenvkeyfnum = 0; if (elm->modenvvelfnum) free_ptr_list(elm->modenvvelf, elm->modenvvelfnum); elm->modenvvelf = NULL, elm->modenvvelfnum = 0; if (elm->trempitch) free(elm->trempitch); elm->trempitch = NULL, elm->trempitchnum = 0; if (elm->tremfc) free(elm->tremfc); elm->tremfc = NULL, elm->tremfcnum = 0; if (elm->modpitch) free(elm->modpitch); elm->modpitch = NULL, elm->modpitchnum = 0; if (elm->modfc) free(elm->modfc); elm->modfc = NULL, elm->modfcnum = 0; if (elm->fc) free(elm->fc); elm->fc = NULL, elm->fcnum = 0; if (elm->reso) free(elm->reso); elm->reso = NULL, elm->resonum = 0;}void free_instruments(int reload_default_inst){ int i = 128 + map_bank_counter, j; struct InstrumentCache *p; ToneBank *bank; Instrument *ip; struct InstrumentCache *default_entry; int default_entry_addr; clear_magic_instruments(); /* Free soundfont instruments */ while(i--) { /* Note that bank[*]->tone[j].instrument may pointer to bank[0]->tone[j].instrument. See play_midi_load_instrument() at playmidi.c for the implementation */ if((bank = tonebank[i]) != NULL) for(j = 127; j >= 0; j--) { ip = bank->tone[j].instrument; if(ip != NULL && ip->type == INST_SF2 && (i == 0 || ip != tonebank[0]->tone[j].instrument)) free_instrument(ip); bank->tone[j].instrument = NULL; } if((bank = drumset[i]) != NULL) for(j = 127; j >= 0; j--) { ip = bank->tone[j].instrument; if(ip != NULL && ip->type == INST_SF2 && (i == 0 || ip != drumset[0]->tone[j].instrument)) free_instrument(ip); bank->tone[j].instrument = NULL; } } /* Free GUS/patch instruments */ default_entry = NULL; default_entry_addr = 0; for(i = 0; i < INSTRUMENT_HASH_SIZE; i++) { p = instrument_cache[i]; while(p != NULL) { if(!reload_default_inst && p->ip == default_instrument) { default_entry = p; default_entry_addr = i; p = p->next; } else { struct InstrumentCache *tmp; tmp = p; p = p->next; free_instrument(tmp->ip); free(tmp); } } instrument_cache[i] = NULL; } if(reload_default_inst) set_default_instrument(NULL); else if(default_entry) { default_entry->next = NULL; instrument_cache[default_entry_addr] = default_entry; }}void free_special_patch(int id){ int i, j, start, end; if(id >= 0) start = end = id; else { start = 0; end = NSPECIAL_PATCH - 1; } for(i = start; i <= end; i++) if(special_patch[i] != NULL) { Sample *sp; int n; if(special_patch[i]->name != NULL) free(special_patch[i]->name); special_patch[i]->name = NULL; n = special_patch[i]->samples; sp = special_patch[i]->sample; if(sp) { for(j = 0; j < n; j++) if(sp[j].data_alloced && sp[j].data) free(sp[j].data); free(sp); } free(special_patch[i]); special_patch[i] = NULL; }}int set_default_instrument(char *name){ Instrument *ip; int i; static char *last_name; if(name == NULL) { name = last_name; if(name == NULL) return 0; } if(!(ip = load_gus_instrument(name, NULL, 0, 0, NULL))) return -1; if(default_instrument) free_instrument(default_instrument); default_instrument = ip; for(i = 0; i < MAX_CHANNELS; i++) default_program[i] = SPECIAL_PROGRAM; last_name = name; return 0;}/*! search mapped bank. returns negative value indicating free bank if not found, 0 if no free bank was available */int find_instrument_map_bank(int dr, int map, int bk){ struct bank_map_elem *bm; int i; if (map == INST_NO_MAP) return 0; bm = dr ? map_drumset : map_bank; for(i = 0; i < MAP_BANK_COUNT; i++) { if (!bm[i].used) return -(128 + i); else if (bm[i].mapid == map && bm[i].bankno == bk) return 128 + i; } return 0;}/*! allocate mapped bank if needed. returns -1 if allocation failed. */int alloc_instrument_map_bank(int dr, int map, int bk){ struct bank_map_elem *bm; int i; if (map == INST_NO_MAP) { alloc_instrument_bank(dr, bk); return bk; } i = find_instrument_map_bank(dr, map, bk); if (i == 0) return -1; if (i < 0) { i = -i - 128; bm = dr ? map_drumset : map_bank; bm[i].used = 1; bm[i].mapid = map; bm[i].bankno = bk; if (map_bank_counter < i + 1) map_bank_counter = i + 1; i += 128; alloc_instrument_bank(dr, i); } return i;}void alloc_instrument_bank(int dr, int bk){ ToneBank *b; if(dr) { if((b = drumset[bk]) == NULL) { b = drumset[bk] = (ToneBank *)safe_malloc(sizeof(ToneBank)); memset(b, 0, sizeof(ToneBank)); } } else { if((b = tonebank[bk]) == NULL) { b = tonebank[bk] = (ToneBank *)safe_malloc(sizeof(ToneBank)); memset(b, 0, sizeof(ToneBank)); } }}/* Instrument alias map - Written by Masanao Izumo */int instrument_map(int mapID, int *set, int *elem){ int s, e; struct inst_map_elem *p; if(mapID == INST_NO_MAP) return 0; /* No map */ s = *set; e = *elem; p = inst_map_table[mapID][s]; if(p != NULL && p[e].mapped) { *set = p[e].set; *elem = p[e].elem; return 1; } if(s != 0) { p = inst_map_table[mapID][0]; if(p != NULL && p[e].mapped) { *set = p[e].set; *elem = p[e].elem; } return 2; } return 0;}void set_instrument_map(int mapID, int set_from, int elem_from, int set_to, int elem_to){ struct inst_map_elem *p; p = inst_map_table[mapID][set_from]; if(p == NULL) { p = (struct inst_map_elem *) safe_malloc(128 * sizeof(struct inst_map_elem)); memset(p, 0, 128 * sizeof(struct inst_map_elem)); inst_map_table[mapID][set_from] = p; } p[elem_from].set = set_to; p[elem_from].elem = elem_to; p[elem_from].mapped = 1;}void free_instrument_map(void){ int i, j; for(i = 0; i < map_bank_counter; i++) map_bank[i].used = map_drumset[i].used = 0; /* map_bank_counter = 0; never shrinks rather than assuming tonebank was already freed */ for (i = 0; i < NUM_INST_MAP; i++) { for (j = 0; j < 128; j++) { struct inst_map_elem *map; map = inst_map_table[i][j]; if (map) { free(map); inst_map_table[i][j] = NULL; } } }}/* Alternate assign - Written by Masanao Izumo */AlternateAssign *add_altassign_string(AlternateAssign *old, char **params, int n){ int i, j; char *p; int beg, end; AlternateAssign *alt; if(n == 0) return old; if(!strcmp(*params, "clear")) { while(old) { AlternateAssign *next; next = old->next; free(old); old = next; } params++; n--; if(n == 0) return NULL; } alt = (AlternateAssign *)safe_malloc(sizeof(AlternateAssign)); memset(alt, 0, sizeof(AlternateAssign)); for(i = 0; i < n; i++) { p = params[i]; if(*p == '-') { beg = 0; p++; } else beg = atoi(p); if((p = strchr(p, '-')) != NULL) { if(p[1] == '\0') end = 127; else end = atoi(p + 1); } else end = beg; if(beg > end) { int t; t = beg; beg = end; end = t; } if(beg < 0) beg = 0; if(end > 127) end = 127; for(j = beg; j <= end; j++) alt->bits[(j >> 5) & 0x3] |= 1 << (j & 0x1F); } alt->next = old; return alt;}AlternateAssign *find_altassign(AlternateAssign *altassign, int note){ AlternateAssign *p; uint32 mask; int idx; mask = 1 << (note & 0x1F); idx = (note >> 5) & 0x3; for(p = altassign; p != NULL; p = p->next) if(p->bits[idx] & mask) return p; return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -