//roarsin.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2012 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include /* libroar */ #ifdef ROAR_HAVE_LIBM #include /* sin() */ #include /* *printf*() */ double rect (double x) { x /= 2*M_PI; x -= (int)x; if ( x < 0.5 ) return 1; else return -1; } double saw (double x) { x /= 2*M_PI; x -= (int)x; return 2*x - 1; } double tri (double x) { x /= 2*M_PI; x -= (int)x; if ( x < 0.5 ) return 4* x - 1; else return -4*(x-0.5) + 1; } double trap (double x) { x /= 2*M_PI; x -= (int)x; if ( x < 0.125 || x > 0.875 ) { return -1; } else if ( x < 0.625 && x > 0.375 ) { return 1; } else if ( x < 0.5 ) { return 8*(x-0.375) + 1; } else { return -8*(x-0.625) + 1; } } static void usage(const char * progname) { fprintf(stderr, "Usage: %s [OPTIONS] [FUNCTION]\n", progname); fprintf(stderr, "\nOptions:\n\n"); fprintf(stderr, " --help - Show this help\n" " --server SERVER - Set server address\n" " --rate -R RATE - Set sample rate to use\n" " --freq FREQ - Set frequency (in Hz)\n" " --time TIME - Set time (in sec)\n" ); fprintf(stderr, "\nFunctions:\n\n"); fprintf(stderr, " --sin - Use Sinus\n" " --rect - Use Rectangle\n" " --saw - Use Saw\n" " --tri - Use Triangle\n" " --trap - Use Trap\n" ); } int main (int argc, char * argv[]) { const char * server = NULL; int rate = ROAR_RATE_DEFAULT; int bits = 16; int channels = 1; /* mono */ int codec = ROAR_CODEC_DEFAULT; float freq = 523.2; /* middle C */ float t = 0; /* current time */ float tcalc = 0; /* current time for calculation */ float length = 5; /* 5 sec */ float step; /* how much time per sample we have to encode ... */ roar_vs_t * vss; int err; int i; int16_t out[1024]; double (*func)(double x) = sin; for (i = 1; i < argc; i++) { if ( !strcmp(argv[i], "--freq") ) { freq = atof(argv[++i]); } else if ( !strcmp(argv[i], "--time") ) { length = atof(argv[++i]); } else if ( !strcmp(argv[i], "--server") ) { server = argv[++i]; } else if ( !strcmp(argv[i], "--rate") || !strcmp(argv[i], "-R") ) { rate = roar_str2rate(argv[++i]); } else if ( !strcmp(argv[i], "--sin") ) { func = sin; } else if ( !strcmp(argv[i], "--rect") ) { func = rect; } else if ( !strcmp(argv[i], "--saw") ) { func = saw; } else if ( !strcmp(argv[i], "--tri") ) { func = tri; } else if ( !strcmp(argv[i], "--trap") ) { func = trap; } else if ( !strcmp(argv[i], "--help") ) { usage(argv[0]); return 0; } else { usage(argv[0]); return 2; } } step = M_PI*2*freq/rate; if ( (vss = roar_vs_new_playback(server, "sine gen", rate, channels, codec, bits, &err)) == NULL ) { fprintf(stderr, "Error: can not open playback: %s\n", roar_vs_strerr(err)); exit(1); } while (t < 2*M_PI*freq*length) { for (i = 0; i < 1024; i++) { out[i] = 32767*func(tcalc); t += step; tcalc += step; } if ( roar_vs_write(vss, out, 2048, &err) != (ssize_t)2048 ) { fprintf(stderr, "Error: can not write data: %s\n", roar_vs_strerr(err)); break; } // this code enables us to generate the same signal for a long periode of time // without loosing accuracy of the float type. while (tcalc > 2*M_PI) tcalc -= 2*M_PI; } roar_vs_close(vss, ROAR_VS_FALSE, NULL); return 0; } #else int main (void) { fprintf(stderr, "Error: No Math library support compiled in.\n"); return 1; } #endif //ll