ref: 6a7c384764bf6d69450037b1fb2ff3dd96b5e81c
dir: /modules/base.c/
/* This code is placed in the public domain. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifndef NO_LIBSNDFILE
#include <sndfile.h>
#endif
#include "soundpipe.h"
int sp_create(sp_data **spp)
{
sp_data *sp;
SPFLOAT *out;
*spp = (sp_data *) malloc(sizeof(sp_data));
sp = *spp;
sprintf(sp->filename, "test.wav");
sp->nchan = 1;
out = malloc(sizeof(SPFLOAT) * sp->nchan);
*out = 0;
sp->out = out;
sp->sr = 44100;
sp->len = 5 * sp->sr;
sp->pos = 0;
sp->rand = 0;
return 0;
}
int sp_createn(sp_data **spp, int nchan)
{
sp_data *sp;
SPFLOAT *out;
*spp = (sp_data *) malloc(sizeof(sp_data));
sp = *spp;
sprintf(sp->filename, "test.wav");
sp->nchan = nchan;
out = malloc(sizeof(SPFLOAT) * sp->nchan);
*out = 0;
sp->out = out;
sp->sr = 44100;
sp->len = 5 * sp->sr;
sp->pos = 0;
sp->rand = 0;
return 0;
}
int sp_destroy(sp_data **spp)
{
sp_data *sp = *spp;
free(sp->out);
free(*spp);
return 0;
}
#ifndef NO_LIBSNDFILE
int sp_process(sp_data *sp, void *ud, void (*callback)(sp_data *, void *))
{
SNDFILE *sf[sp->nchan];
char tmp[140];
SF_INFO info;
memset(&info, 0, sizeof(SF_INFO));
SPFLOAT buf[sp->nchan][SP_BUFSIZE];
info.samplerate = sp->sr;
info.channels = 1;
info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_24;
int numsamps, i, chan;
if (sp->nchan == 1) {
sf[0] = sf_open(sp->filename, SFM_WRITE, &info);
} else {
for (chan = 0; chan < sp->nchan; chan++) {
sprintf(tmp, "%02d_%s", chan, sp->filename);
sf[chan] = sf_open(tmp, SFM_WRITE, &info);
}
}
while (sp->len > 0) {
if (sp->len < SP_BUFSIZE) {
numsamps = sp->len;
} else {
numsamps = SP_BUFSIZE;
}
for (i = 0; i < numsamps; i++) {
callback(sp, ud);
for (chan = 0; chan < sp->nchan; chan++) {
buf[chan][i] = sp->out[chan];
}
sp->pos++;
}
for (chan = 0; chan < sp->nchan; chan++) {
#ifdef USE_DOUBLE
sf_write_double(sf[chan], buf[chan], numsamps);
#else
sf_write_float(sf[chan], buf[chan], numsamps);
#endif
}
sp->len -= numsamps;
}
for (i = 0; i < sp->nchan; i++) {
sf_close(sf[i]);
}
return 0;
}
#endif
int sp_process_raw(sp_data *sp, void *ud, void (*callback)(sp_data *, void *))
{
int chan;
if (sp->len == 0) {
while(1) {
callback(sp, ud);
for (chan = 0; chan < sp->nchan; chan++) {
fwrite(&sp->out[chan], sizeof(SPFLOAT), 1, stdout);
}
sp->len--;
}
} else {
while (sp->len > 0) {
callback(sp, ud);
for (chan = 0; chan < sp->nchan; chan++) {
fwrite(&sp->out[chan], sizeof(SPFLOAT), 1, stdout);
}
sp->len--;
sp->pos++;
}
}
return SP_OK;
}
int sp_process_plot(sp_data *sp, void *ud, void (*callback)(sp_data *, void *))
{
int chan;
fprintf(stdout, "sp_out = [ ... \n");
while (sp->len > 0) {
callback(sp, ud);
for (chan = 0; chan < sp->nchan; chan++) {
/* fwrite(&sp->out[chan], sizeof(SPFLOAT), 1, stdout); */
fprintf(stdout, "%g ", sp->out[chan]);
}
fprintf(stdout, "; ...\n");
sp->len--;
sp->pos++;
}
fprintf(stdout, "];\n");
fprintf(stdout, "plot(sp_out);\n");
fprintf(stdout, "title('Plot generated by Soundpipe');\n");
fprintf(stdout, "xlabel('Time (samples)');\n");
fprintf(stdout, "ylabel('Amplitude');\n");
return SP_OK;
}
SPFLOAT sp_midi2cps(SPFLOAT nn)
{
return pow(2, (nn - 69.0) / 12.0) * 440.0;
}
int sp_set(sp_param *p, SPFLOAT val) {
p->state = 1;
p->val = val;
return SP_OK;
}
int sp_out(sp_data *sp, uint32_t chan, SPFLOAT val)
{
if (chan > sp->nchan - 1) {
fprintf(stderr, "sp_out: Invalid channel\n");
return SP_NOT_OK;
}
sp->out[chan] = val;
return SP_OK;
}
uint32_t sp_rand(sp_data *sp)
{
uint32_t val = (1103515245 * sp->rand + 12345) % SP_RANDMAX;
sp->rand = val;
return val;
}
void sp_srand(sp_data *sp, uint32_t val)
{
sp->rand = val;
}