diff options
author | Michiel Van Der Kolk <not.valid@email.address> | 2005-03-17 20:50:03 +0000 |
---|---|---|
committer | Michiel Van Der Kolk <not.valid@email.address> | 2005-03-17 20:50:03 +0000 |
commit | 27be5bc72855a0fbbdae230bc144624c9eb85f5e (patch) | |
tree | b553f1321df924c4b744ffcab48dce5f4f081f7d /apps/codecs/dumb/examples | |
parent | 7e7662bb716917ca431204f0113d400c1014f2e8 (diff) |
Initial check in dumb 0.9.2 - has a few usages of floating point that should
be rewritten to fixed point. seems to compile cleanly for iriver.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6197 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/dumb/examples')
-rw-r--r-- | apps/codecs/dumb/examples/dumb.ini | 44 | ||||
-rw-r--r-- | apps/codecs/dumb/examples/dumbout.c | 335 | ||||
-rw-r--r-- | apps/codecs/dumb/examples/dumbplay.c | 238 |
3 files changed, 617 insertions, 0 deletions
diff --git a/apps/codecs/dumb/examples/dumb.ini b/apps/codecs/dumb/examples/dumb.ini new file mode 100644 index 0000000000..6fea2ce50f --- /dev/null +++ b/apps/codecs/dumb/examples/dumb.ini @@ -0,0 +1,44 @@ +# Please edit this file to control the playback quality for 'dumbplay'. Note +# that this does not affect DUMB when you use it in your own programs; you +# need to borrow some code from the example program in order to get that to +# happen. + +# dumb_resampling_quality can be 0 for aliasing, 1 for linear interpolation +# or 2 for cubic interpolation. See docs/dumb.txt for details on what these +# terms mean. + +# dumb_it_max_to_mix is the maximum number of samples DUMB will render at a +# time. See docs/dumb.txt for a more detailed description. + +# Increase buffer_size to combat stuttering. + +# The music module will be rendered at the sampling frequency specified by +# sound_freq. This variable is also used by Allegro for initialising the +# sound hardware. + +# buffer_size and sound_freq are passed directly to al_start_duh(). See this +# function's description in docs/dumb.txt for information about how to use +# these variables. + +# You can ignore the quality variable. Allegro uses it when relaying the +# audio stream to the sound card. Only a masochist would set it lower than 2; +# if your computer is powerful enough to run DUMB, it is powerful enough to +# use this setting with Allegro. + +# For best results, choose a value for sound_freq that your sound card can do +# exactly. See Allegro's docs, "Standard config variables", for details. If +# you do not choose an exact value, Allegro will round it to the nearest +# value it can do; then when DUMB plays the stream at a sampling frequency of +# sound_freq, Allegro will have to resample it. Allegro's 'quality = 2' +# setting is only comparable with DUMB's 'dumb_resampling_quality = 1' +# setting. Therefore, in order to appreciate DUMB's cubic resampler fully, +# you will need to make sure Allegro doesn't do any resampling, by choosing +# an exact value for sound_freq. + +[sound] +dumb_resampling_quality = 2 +dumb_it_max_to_mix = 256 +buffer_size = 4096 +sound_freq = 44100 + +quality = 2 diff --git a/apps/codecs/dumb/examples/dumbout.c b/apps/codecs/dumb/examples/dumbout.c new file mode 100644 index 0000000000..b0ead3dd5e --- /dev/null +++ b/apps/codecs/dumb/examples/dumbout.c @@ -0,0 +1,335 @@ +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * dumbout.c - Utility to stream music to a file. / / \ \ + * | < / \_ + * By entheh. | \/ /\ / + * \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <math.h> +#include <string.h> +#include <dumb.h> + + +union { + short s16[8192]; + char s8[16384]; +} buffer; + + +int main(int argc, const char *const *argv) /* I'm const-crazy! */ +{ + DUH *duh; + DUH_SIGRENDERER *sr; + + const char *fn = NULL; + const char *fn_out = NULL; + FILE *outf; + + int depth = 16; + int bigendian = 0; + int unsign = 0; + int freq = 44100; + int n_channels = 2; + float volume = 1.0f; + float delay = 0.0f; + float delta; + int bufsize; + clock_t start, end; + + int i = 1; + + LONG_LONG length; + LONG_LONG done; + int dots; + + while (i < argc) { + const char *arg = argv[i++]; + if (*arg != '-') { + if (fn) { + fprintf(stderr, + "Cannot specify multiple filenames!\n" + "Second filename found: \"%s\"\n", arg); + return 1; + } + fn = arg; + continue; + } + arg++; + while (*arg) { + char *endptr; + switch (*arg++) { + case 'o': + case 'O': + if (i >= argc) { + fprintf(stderr, "Out of arguments; output filename expected!\n"); + return 1; + } + fn_out = argv[i++]; + break; + case 'd': + case 'D': + if (i >= argc) { + fprintf(stderr, "Out of arguments; delay expected!\n"); + return 1; + } + delay = (float)strtod(argv[i++], &endptr); + if (*endptr != 0 || delay < 0.0f || delay > 64.0f) { + fprintf(stderr, "Invalid delay!\n"); + return 1; + } + break; + case 'v': + case 'V': + if (i >= argc) { + fprintf(stderr, "Out of arguments; volume expected!\n"); + return 1; + } + volume = (float)strtod(argv[i++], &endptr); + if (*endptr != 0 || volume < -8.0f || volume > 8.0f) { + fprintf(stderr, "Invalid volume!\n"); + return 1; + } + break; + case 's': + case 'S': + if (i >= argc) { + fprintf(stderr, "Out of arguments; sampling rate expected!\n"); + return 1; + } + freq = strtol(argv[i++], &endptr, 10); + if (*endptr != 0 || freq < 1 || freq > 960000) { + fprintf(stderr, "Invalid sampling rate!\n"); + return 1; + } + break; + case '8': + depth = 8; + break; + case 'b': + case 'B': + bigendian = 1; + break; + case 'm': + case 'M': + n_channels = 1; + break; + case 'u': + case 'U': + unsign = 1; + break; + case 'r': + case 'R': + if (i >= argc) { + fprintf(stderr, "Out of arguments; resampling quality expected!\n"); + return 1; + } + dumb_resampling_quality = strtol(argv[i++], &endptr, 10); + if (*endptr != 0 || dumb_resampling_quality < 0 || dumb_resampling_quality > 2) { + fprintf(stderr, "Invalid resampling quality!\n"); + return 1; + } + break; + default: + fprintf(stderr, "Invalid switch - '%c'!\n", isprint(arg[-1]) ? arg[-1] : '?'); + return 1; + } + } + } + + if (!fn) { + fprintf(stderr, + "Usage: dumbout [options] module [more-options]\n" + "\n" + "The module can be any IT, XM, S3M or MOD file. It will be rendered to a .pcm\n" + "file of the same name, unless you specify otherwise with the -o option.\n" + "\n" + "The valid options are:\n" + "-o <file> specify the output filename (defaults to the input filename with\n" + " the extension replaced with .pcm); use - to write to standard\n" + " output or . to write nowhere (useful for measuring DUMB's\n" + " performance, and DOS and Windows don't have /dev/null!)\n" + "-d <delay> set the initial delay, in seconds (default 0.0)\n" + "-v <volume> adjust the volume (default 1.0)\n" + "-s <freq> set the sampling rate in Hz (default 44100)\n" + "-8 generate 8-bit instead of 16-bit\n" + "-b generate big-endian data instead of little-endian (meaningless when\n" + " using -8)\n" + "-m generate mono output instead of stereo left/right pairs\n" + "-u generated unsigned output instead of signed\n" + "-r <value> specify the resampling quality to use\n"); + return 1; + } + + atexit(&dumb_exit); + dumb_register_stdfiles(); + + dumb_it_max_to_mix = 256; + + duh = load_duh(fn); + if (!duh) { + duh = dumb_load_it(fn); + if (!duh) { + duh = dumb_load_xm(fn); + if (!duh) { + duh = dumb_load_s3m(fn); + if (!duh) { + duh = dumb_load_mod(fn); + if (!duh) { + fprintf(stderr, "Unable to open %s!\n", fn); + return 1; + } + } + } + } + } + + sr = duh_start_sigrenderer(duh, 0, n_channels, 0); + if (!sr) { + unload_duh(duh); + fprintf(stderr, "Unable to play file!\n"); + return 1; + } + + if (fn_out) { + if (fn_out[0] == '-' && fn_out[1] == 0) + outf = stdout; + else if (fn_out[0] == '.' && fn_out[1] == 0) + outf = NULL; + else { + outf = fopen(fn_out, "wb"); + if (!outf) { + fprintf(stderr, "Unable to open %s for writing!\n", fn_out); + duh_end_sigrenderer(sr); + unload_duh(duh); + return 1; + } + } + } else { + char *extptr = NULL, *p; + char *fn_out = malloc(strlen(fn)+5); + if (!fn_out) { + fprintf(stderr, "Out of memory!\n"); + duh_end_sigrenderer(sr); + unload_duh(duh); + return 1; + } + strcpy(fn_out, fn); + for (p = fn_out; *p; p++) + if (*p == '.') extptr = p; + if (!extptr) extptr = p; + strcpy(extptr, ".pcm"); + outf = fopen(fn_out, "wb"); + if (!outf) { + fprintf(stderr, "Unable to open %s for writing!\n", fn_out); + free(fn_out); + duh_end_sigrenderer(sr); + unload_duh(duh); + return 1; + } + free(fn_out); + } + + { + DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); + dumb_it_set_loop_callback(itsr, &dumb_it_callback_terminate, NULL); + dumb_it_set_xm_speed_zero_callback(itsr, &dumb_it_callback_terminate, NULL); + } + + length = (LONG_LONG)duh_get_length(duh) * freq >> 16; + done = 0; + dots = 0; + delta = 65536.0f / freq; + bufsize = depth == 16 ? 8192 : 16384; + bufsize /= n_channels; + + { + long l = (long)floor(delay * freq + 0.5f); + l *= n_channels * (depth >> 3); + if (l) { + if (unsign) { + if (depth == 16) { + if (bigendian) { + for (i = 0; i < 8192; i++) { + buffer.s8[i*2] = 0x80; + buffer.s8[i*2+1] = 0x00; + } + } else { + for (i = 0; i < 8192; i++) { + buffer.s8[i*2] = 0x00; + buffer.s8[i*2+1] = 0x80; + } + } + } else + memset(buffer.s8, 0x80, 16384); + } else + memset(buffer.s8, 0, 16384); + while (l >= 16384) { + if (outf) fwrite(buffer.s8, 1, 16384, outf); + l -= 16384; + } + if (l && outf) fwrite(buffer.s8, 1, l, outf); + } + } + + start = clock(); + + fprintf(stderr, "................................................................\n"); + for (;;) { + int l = duh_render(sr, depth, unsign, volume, delta, bufsize, &buffer); + if (depth == 16) { + if (bigendian) { + for (i = 0; i < l * n_channels; i++) { + short val = buffer.s16[i]; + buffer.s8[i*2] = val >> 8; + buffer.s8[i*2+1] = val; + } + } else { + for (i = 0; i < l * n_channels; i++) { + short val = buffer.s16[i]; + buffer.s8[i*2] = val; + buffer.s8[i*2+1] = val >> 8; + } + } + } + if (outf) fwrite(buffer.s8, 1, l * n_channels * (depth >> 3), outf); + if (l < bufsize) break; + done += l; + l = done * 64 / length; + while (dots < 64 && l > dots) { + fprintf(stderr, "|"); + dots++; + } + } + + while (64 > dots) { + fprintf(stderr, "|"); + dots++; + } + fprintf(stderr, "\n"); + + end = clock(); + + duh_end_sigrenderer(sr); + unload_duh(duh); + if (outf && outf != stdout) fclose(outf); + + fprintf(stderr, "Elapsed time: %f seconds\n", (end - start) / (float)CLOCKS_PER_SEC); + + return 0; +} diff --git a/apps/codecs/dumb/examples/dumbplay.c b/apps/codecs/dumb/examples/dumbplay.c new file mode 100644 index 0000000000..6421cfdf34 --- /dev/null +++ b/apps/codecs/dumb/examples/dumbplay.c @@ -0,0 +1,238 @@ +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * dumbplay.c - Not-so-simple program to play / / \ \ + * music. It used to be simpler! | < / \_ + * | \/ /\ / + * By entheh. \_ / > / + * | \ / / + * IMPORTANT NOTE: This file is not very friendly. | ' / + * I strongly recommend AGAINST using it as a \__/ + * reference for writing your own code. If you would + * like to write a program that uses DUMB, or add DUMB to an existing + * project, please use docs/howto.txt. It will help you a lot more than this + * file can. (If you have difficulty reading documentation, you are lacking + * an important coding skill, and now is as good a time as any to learn.) + */ + +#include <stdlib.h> +#include <allegro.h> + +#ifndef ALLEGRO_DOS +#include <string.h> +#endif + +/* Note that your own programs should use <aldumb.h> not "aldumb.h". <> tells + * the compiler to look in the compiler's default header directory, which is + * where DUMB should be installed before you use it (make install does this). + * Use "" when it is your own header file. This example uses "" because DUMB + * might not have been installed yet when the makefile builds it. + */ +#include "aldumb.h" + + + +#ifndef ALLEGRO_DOS +static volatile int closed = 0; +static void closehook(void) { closed = 1; } +#else +#define closed 0 +#endif + +#ifdef ALLEGRO_WINDOWS +#define GFX_DUMB_MODE GFX_GDI +#include <winalleg.h> +#define YIELD() Sleep(1) +#else +#define GFX_DUMB_MODE GFX_AUTODETECT_WINDOWED +#ifdef ALLEGRO_UNIX +#include <sys/time.h> +static void YIELD(void) +{ + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 1; + select(0, NULL, NULL, NULL, &tv); +} +#else +#define YIELD() yield_timeslice() +#endif +#endif + + + +#ifdef ALLEGRO_DOS +static int loop_callback(void *data) +{ + (void)data; + printf("Music has looped.\n"); + return 0; +} + +static int xm_speed_zero_callback(void *data) +{ + (void)data; + printf("Music has stopped.\n"); + return 0; +} +#else +static int gfx_half_width; + +static int loop_callback(void *data) +{ + (void)data; + if (gfx_half_width) { + acquire_screen(); + textout_centre(screen, font, "Music has looped.", gfx_half_width, 36, 10); + release_screen(); + } + return 0; +} + +static int xm_speed_zero_callback(void *data) +{ + (void)data; + if (gfx_half_width) { + text_mode(0); /* In case this is overwriting "Music has looped." */ + acquire_screen(); + textout_centre(screen, font, "Music has stopped.", gfx_half_width, 36, 10); + release_screen(); + } + return 0; +} +#endif + + + +static void usage(const char *exename) +{ + allegro_message( +#ifdef ALLEGRO_WINDOWS + "Usage:\n" + " At the command line: %s file\n" + " In Windows Explorer: drag a file on to this program's icon.\n" +#else + "Usage: %s file\n" +#endif + "This will play the music file specified.\n" + "File formats supported: IT XM S3M MOD.\n" + "You can control playback quality by editing dumb.ini.\n", exename); + + exit(1); +} + + + +int main(int argc, const char *const *argv) /* I'm const-crazy! */ +{ + DUH *duh; + AL_DUH_PLAYER *dp; + + if (allegro_init()) + return 1; + + if (argc != 2) + usage(argv[0]); + + set_config_file("dumb.ini"); + + if (install_keyboard()) { + allegro_message("Failed to initialise keyboard driver!\n"); + return 1; + } + + set_volume_per_voice(0); + + if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL)) { + allegro_message("Failed to initialise sound driver!\n%s\n", allegro_error); + return 1; + } + + atexit(&dumb_exit); + + dumb_register_packfiles(); + + duh = dumb_load_it(argv[1]); + if (!duh) { + duh = dumb_load_xm(argv[1]); + if (!duh) { + duh = dumb_load_s3m(argv[1]); + if (!duh) { + duh = dumb_load_mod(argv[1]); + if (!duh) { + allegro_message("Failed to load %s!\n", argv[1]); + return 1; + } + } + } + } + + dumb_resampling_quality = get_config_int("sound", "dumb_resampling_quality", 4); + dumb_it_max_to_mix = get_config_int("sound", "dumb_it_max_to_mix", 128); + +#ifndef ALLEGRO_DOS + { + const char *fn = get_filename(argv[1]); + gfx_half_width = strlen(fn); + if (gfx_half_width < 22) gfx_half_width = 22; + gfx_half_width = (gfx_half_width + 2) * 4; + + /* set_window_title() is not const-correct (yet). */ + set_window_title((char *)"DUMB Music Player"); + + if (set_gfx_mode(GFX_DUMB_MODE, gfx_half_width*2, 80, 0, 0) == 0) { + acquire_screen(); + textout_centre(screen, font, fn, gfx_half_width, 20, 14); + textout_centre(screen, font, "Press any key to exit.", gfx_half_width, 52, 11); + release_screen(); + } else + gfx_half_width = 0; + } + +#if ALLEGRO_VERSION*10000 + ALLEGRO_SUB_VERSION*100 + ALLEGRO_WIP_VERSION >= 40105 + set_close_button_callback(&closehook); +#else + set_window_close_hook(&closehook); +#endif + +#endif + + set_display_switch_mode(SWITCH_BACKGROUND); + + dp = al_start_duh(duh, 2, 0, 1.0f, + get_config_int("sound", "buffer_size", 4096), + get_config_int("sound", "sound_freq", 44100)); + + { + DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(dp); + DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); + dumb_it_set_loop_callback(itsr, &loop_callback, NULL); + dumb_it_set_xm_speed_zero_callback(itsr, &xm_speed_zero_callback, NULL); + } + + for (;;) { + if (keypressed()) { + readkey(); + break; + } + + if (al_poll_duh(dp) || closed) + break; + + YIELD(); + } + + al_stop_duh(dp); + + unload_duh(duh); + + return 0; +} +END_OF_MAIN(); |