ref: 2e86b938c226edc0d8bd6c3855baf3bec02b5179
dir: /modules/nsmp.c/
/* This code is placed in the public domain. */ #include <stdlib.h> #include <string.h> #include <math.h> #include "soundpipe.h" #include "ini.h" int nano_dict_add(nano_dict *dict, const char *name) { nano_entry *entry = malloc(sizeof(nano_entry)); entry->size = 0; entry->speed = 1; entry->pos = 0; strcpy(entry->name, name); dict->last->next = entry; dict->last = entry; dict->nval++; return SP_OK; } int nano_ini_handler(void *user, const char *section, const char *name, const char *value) { nanosamp *ss = user; nano_dict *dict = &ss->dict; const char *entry_name = dict->last->name; if (dict->init) { nano_dict_add(dict, section); dict->init = 0; } else if(strncmp(entry_name, section, 50) != 0) { nano_dict_add(dict, section); } dict->last->speed = 1.0; if (strcmp(name, "pos") == 0) { dict->last->pos = (uint32_t)(atof(value) * ss->sr); } else if (strcmp(name, "size") == 0) { dict->last->size = (uint32_t)(atof(value) * ss->sr); } else if (strcmp(name, "speed") == 0) { dict->last->speed = atof(value); } return SP_OK; } int nano_create(nanosamp **smp, const char *ini, int sr) { nanosamp *psmp; *smp = malloc(sizeof(nanosamp)); psmp = *smp; strcpy(psmp->ini, ini); psmp->dict.last = &psmp->dict.root; psmp->dict.nval = 0; psmp->dict.init = 1; psmp->selected = 0; psmp->curpos = 0; psmp->sr = sr; if (ini_parse(psmp->ini, nano_ini_handler, psmp) < 0) { printf("Can't load file %s\n", psmp->ini); return SP_NOT_OK; } return SP_OK; } int nano_select_from_index(nanosamp *smp, uint32_t pos) { pos %= smp->dict.nval; smp->selected = 1; smp->sample = smp->index[pos]; smp->curpos = 0; return SP_OK; } uint32_t nano_keyword_to_index(nanosamp *smp, const char *keyword) { uint32_t i; for (i = 0; i < smp->dict.nval; i++) { if (strcmp(keyword, smp->index[i]->name)) { return i; } } return 0; } int nano_select(nanosamp *smp, const char *keyword) { uint32_t i; nano_dict *dict = &smp->dict; nano_entry *entry = dict->root.next; smp->curpos = 0; smp->selected = 0; for (i = 0; i < dict->nval; i++) { if (strncmp(keyword, entry->name, 50) == 0) { smp->selected = 1; smp->sample = entry; smp->curpos = 0; break; } else { entry = entry->next; } } if (smp->selected == 1) return SP_OK; else return SP_NOT_OK; } int nano_compute(sp_data *sp, nanosamp *smp, SPFLOAT *out) { if (!smp->selected) { *out = 0; return SP_NOT_OK; } if (smp->curpos < (SPFLOAT)smp->sample->size) { SPFLOAT x1 = 0 , x2 = 0, frac = 0, tmp = 0; uint32_t index = 0; SPFLOAT *tbl = smp->ft->tbl; tmp = (smp->curpos + smp->sample->pos); index = floorf(tmp); frac = fabs(tmp - index); if (index >= smp->ft->size) { index = smp->ft->size - 1; } x1 = tbl[index]; x2 = tbl[index + 1]; *out = x1 + (x2 - x1) * frac; smp->curpos += smp->sample->speed; } else { smp->selected = 0; *out = 0; } return SP_OK; } int nano_dict_destroy(nano_dict *dict) { int i; nano_entry *entry, *next; entry = dict->root.next; for (i = 0; i < dict->nval; i++) { next = entry->next; free(entry); entry = next; } return SP_OK; } int nano_destroy(nanosamp **smp) { nanosamp *psmp = *smp; nano_dict_destroy(&psmp->dict); free(*smp); return SP_OK; } int nano_create_index(nanosamp *smp) { int i; nano_entry *entry, *next; nano_dict *dict = &smp->dict; smp->index = malloc(dict->nval * sizeof(nano_entry *)); entry = dict->root.next; for (i = 0; i < dict->nval; i++) { next = entry->next; smp->index[i] = entry; entry = next; } return SP_OK; } int nano_destroy_index(nanosamp *smp) { free(smp->index); return SP_OK; } int sp_nsmp_create(sp_nsmp **p) { *p = malloc(sizeof(sp_nsmp)); return SP_OK; } int sp_nsmp_destroy(sp_nsmp **p) { sp_nsmp *pp = *p; nano_destroy_index(pp->smp); nano_destroy(&pp->smp); free(*p); return SP_OK; } int sp_nsmp_init(sp_data *sp, sp_nsmp *p, sp_ftbl *ft, int sr, const char *ini) { if (nano_create(&p->smp, ini, sr) == SP_NOT_OK) { nano_destroy(&p->smp); return SP_NOT_OK; } nano_create_index(p->smp); p->smp->sr = sr; p->index= 0; p->triggered = 0; p->smp->ft = ft; return SP_OK; } int sp_nsmp_compute(sp_data *sp, sp_nsmp *p, SPFLOAT *trig, SPFLOAT *out) { if (*trig != 0) { p->triggered = 1; nano_select_from_index(p->smp, p->index); } if (p->triggered == 1) { nano_compute(sp, p->smp, out); } else { *out = 0; } return SP_OK; } int sp_nsmp_print_index(sp_data *sp, sp_nsmp *p) { uint32_t i; for (i = 0; i < p->smp->dict.nval; i++) { printf("%d: key = %s\n", i, p->smp->index[i]->name); } return SP_OK; }