|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /* sndplay plays sounds */
-
- #include "mus-config.h"
-
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- #include "_sndlib.h"
-
- #ifndef _MSC_VER
- #include <unistd.h>
- #endif
- #include <string.h>
-
- #if __APPLE__
- #define BUFFER_SIZE 256
- #else
- #ifdef _MSC_VER
- /* this setting from Scott Middleton (actually used 8096) */
- #define BUFFER_SIZE 8192
- #else
- #define BUFFER_SIZE 4096
- #endif
- #endif
-
- #if __APPLE__
- #define OutSample float
- #define MUS_CONVERT(samp) (float)(samp)
- #else
- #define OutSample short
- #define MUS_SAMPLE_TO_SHORT(n) ((short)((n) * (1 << 15)))
- #define MUS_CONVERT(samp) MUS_SAMPLE_TO_SHORT(samp)
- #endif
-
-
- /* 22-Nov-00: moved alsa support to separate block */
- /* 8-Apr-04: added start/end (seconds-based) args */
- /* 2-Nov-05: added -volume arg (removed later) */
- /* 22-July-08: added -mutable arg */
- /* 1-May-12: removed alsa special case */
-
-
- int main(int argc, char *argv[])
- {
- int fd, afd, i, j, n, k, chans, srate;
- mus_long_t framples, m;
- mus_float_t **bufs;
- OutSample *obuf;
- int buffer_size = BUFFER_SIZE, curframples, sample_size, out_chans, outbytes;
- char *name = NULL;
- mus_long_t start = 0, end = 0;
- double begin_time = 0.0, end_time = 0.0;
- int mutate = 1, include_mutate = 0;
-
- if (argc == 1)
- {
- printf("usage: sndplay file [-start 1.0] [-end 1.0] [-bufsize %d] [-buffers 2x12] [-describe]\n", BUFFER_SIZE);
- exit(0);
- }
- mus_sound_initialize();
-
- for (i = 1; i < argc; i++)
- {
- if (strcmp(argv[i], "-buffers") == 0)
- {
- #if (HAVE_OSS || HAVE_ALSA)
- static char x_string[2] = {'x','\0'};
- char *arg;
- int a, b;
- arg = strtok(argv[i + 1], x_string);
- a = atoi(arg);
- arg = strtok(NULL, x_string);
- b = atoi(arg);
- mus_oss_set_buffers(a, b);
- #endif
- i++;
- }
- else
- {
- if (strcmp(argv[i], "-bufsize") == 0)
- {
- buffer_size = atoi(argv[i + 1]);
- i++;
- }
- else
- {
- if (strcmp(argv[i], "-start") == 0)
- {
- begin_time = atof(argv[i + 1]);
- i++;
- }
- else
- {
- if (strcmp(argv[i], "-end") == 0)
- {
- end_time = atof(argv[i + 1]);
- i++;
- }
- else
- {
- if (strcmp(argv[i], "-mutable") == 0)
- {
- mutate = atoi(argv[i + 1]);
- include_mutate = 1;
- i++;
- }
- else name = argv[i];
- }}}}}
-
- if (name == NULL)
- {
- printf("usage: sndplay file [-start 1.0] [-end 1.0] [-bufsize %d] [-buffers 2x12] [-mutable 1]\n", BUFFER_SIZE);
- exit(0);
- }
-
- afd = -1;
-
- if (!(mus_is_header_type(mus_sound_header_type(name))))
- {
- fprintf(stderr, "can't play %s (header type: %s?)\n",
- name,
- mus_header_type_name(mus_header_type()));
- exit(0);
- }
-
- if (!(mus_is_sample_type(mus_sound_sample_type(name))))
- {
- fprintf(stderr, "can't play %s (sample type: %s (%s)?)\n",
- name,
- mus_sample_type_name(mus_sound_sample_type(name)),
- mus_header_original_sample_type_name(mus_sound_original_sample_type(name), mus_sound_header_type(name)));
- exit(0);
- }
-
- fd = mus_sound_open_input(name);
- if (fd != -1)
- {
- chans = mus_sound_chans(name);
- if (chans > 2)
- {
- int available_chans;
- available_chans = mus_audio_device_channels(MUS_AUDIO_DEFAULT);
- if (available_chans < chans)
- {
- fprintf(stderr, "%s has %d channels, but we can only handle %d\n", name, chans, available_chans);
- exit(1);
- }
- }
-
- out_chans = chans;
- srate = mus_sound_srate(name);
- framples = mus_sound_framples(name);
- sample_size = mus_bytes_per_sample(MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE);
- start = (mus_long_t)(begin_time * srate);
- if (start > 0)
- mus_file_seek_frample(fd, start);
- if (end_time > 0.0)
- end = (mus_long_t)(end_time * srate);
- else end = framples;
- if ((end - start) < framples)
- framples = end - start;
-
- bufs = (mus_float_t **)calloc(chans, sizeof(mus_float_t *));
- for (i = 0; i < chans; i++) bufs[i] = (mus_float_t *)calloc(buffer_size, sizeof(mus_float_t));
- obuf = (OutSample *)calloc(buffer_size * out_chans, sizeof(OutSample));
- outbytes = buffer_size * out_chans * sample_size;
-
- for (m = 0; m < framples; m += buffer_size)
- {
- if ((m + buffer_size) <= framples)
- curframples = buffer_size;
- else curframples = framples - m;
- mus_file_read(fd, start + m, curframples, chans, bufs);
- /* some systems are happier if we read the file before opening the dac */
- /* at this point the data is in separate arrays of mus_sample_t's */
-
- if (chans == 1)
- {
- for (k = 0; k < curframples; k++)
- obuf[k] = MUS_CONVERT(bufs[0][k]);
- }
- else
- {
- if (chans == 2)
- {
- for (k = 0, n = 0; k < curframples; k++, n += 2)
- {
- obuf[n] = MUS_CONVERT(bufs[0][k]);
- obuf[n + 1] = MUS_CONVERT(bufs[1][k]);
- }
- }
- else
- {
- for (k = 0, j = 0; k < curframples; k++, j += chans)
- {
- for (n = 0; n < chans; n++)
- obuf[j + n] = MUS_CONVERT(bufs[n][k]);
- }
- }
- }
- #if __APPLE__
- if (include_mutate == 1)
- mus_audio_output_properties_mutable(mutate);
- #endif
- if (afd == -1)
- {
- afd = mus_audio_open_output(MUS_AUDIO_DEFAULT, srate, out_chans, MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE, outbytes);
- if (afd == -1) break;
- }
- outbytes = curframples * out_chans * sample_size;
- mus_audio_write(afd, (char *)obuf, outbytes);
- }
- if (afd != -1) mus_audio_close(afd);
- mus_sound_close_input(fd);
- for (i = 0; i < chans; i++) free(bufs[i]);
- free(bufs);
- free(obuf);
- }
- return(0);
- }
|