static int main_not_alsa(int argc, char *argv[]) { int fd, afd, i, j, n, k, chans, srate; off_t frames, m; mus_sample_t **bufs; OutSample *obuf; int use_multi_card_code = 0, use_volume = 0; int afd0, afd1, buffer_size = BUFFER_SIZE, curframes, sample_size, out_chans, outbytes; mus_sample_t **qbufs; short *obuf0, *obuf1; char *name = NULL; off_t start = 0, end = 0; double begin_time = 0.0, end_time = 0.0, volume = 1.0; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-describe") == 0) { mus_audio_describe(); exit(0); } else { if (strcmp(argv[i], "-buffers") == 0) { set_buffers(argv[i + 1]); 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], "-volume") == 0) { volume = atof(argv[i + 1]); use_volume = 1; i++; } else name = argv[i]; }}}}}} if (name == NULL) { printf("usage: sndplay file [-start 1.0] [-end 1.0] [-bufsize %d] [-buffers 2x12] [-volume 1.0] [-describe]\n", BUFFER_SIZE); exit(0); } afd = -1; afd0 = -1; afd1 = -1; if (!(MUS_HEADER_TYPE_OK(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_DATA_FORMAT_OK(mus_sound_data_format(name)))) { fprintf(stderr, "can't play %s (data format: %s (%s)?)\n", name, mus_data_format_name(mus_sound_data_format(name)), mus_header_original_format_name(mus_sound_original_format(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) { float val[8]; mus_audio_mixer_read(MUS_AUDIO_DEFAULT, MUS_AUDIO_CHANNEL, 0, val); if (val[0] < chans) { if (mus_audio_systems() > 1) use_multi_card_code = 1; /* I suppose we could count up all the channels here */ else { fprintf(stderr, "%s has %d channels, but we can only handle %d\n", name, chans, (int)(val[0])); exit(1); } } } out_chans = chans; srate = mus_sound_srate(name); frames = mus_sound_frames(name); sample_size = mus_bytes_per_sample(MUS_AUDIO_COMPATIBLE_FORMAT); start = (off_t)(begin_time * srate); if (start > 0) mus_file_seek_frame(fd, start); if (end_time > 0.0) end = (off_t)(end_time * srate); else end = frames; if ((end - start) < frames) frames = end - start; if (!use_multi_card_code) { bufs = (mus_sample_t **)calloc(chans, sizeof(mus_sample_t *)); for (i = 0; i < chans; i++) bufs[i] = (mus_sample_t *)calloc(buffer_size, sizeof(mus_sample_t)); obuf = (OutSample *)calloc(buffer_size * out_chans, sizeof(OutSample)); outbytes = buffer_size * out_chans * sample_size; for (m = 0; m < frames; m += buffer_size) { if ((m + buffer_size) <= frames) curframes = buffer_size; else curframes = frames - m; mus_file_read(fd, 0, curframes - 1, 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 (use_volume) set_volume(bufs, chans, curframes, volume); if (chans == 1) { for (k = 0; k < curframes; k++) obuf[k] = MUS_CONVERT(bufs[0][k]); } else { if (chans == 2) { for (k = 0, n = 0; k < curframes; 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 < curframes; k++, j += chans) { for (n = 0; n < chans; n++) obuf[j + n] = MUS_CONVERT(bufs[n][k]); } } } if (afd == -1) { #if defined(MUS_LINUX) && defined(PPC) afd = mus_audio_open_output(MUS_AUDIO_DEFAULT, srate, chans, MUS_AUDIO_COMPATIBLE_FORMAT, 0); #else afd = mus_audio_open_output(MUS_AUDIO_DEFAULT, srate, out_chans, MUS_AUDIO_COMPATIBLE_FORMAT, outbytes); #endif if (afd == -1) break; } outbytes = curframes * 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); } else { /* code is essentially the same as above, but since this is supposed * to be a working example of sndlib, I didn't want the basic stuff * to be complicated by one special case. * * in my test case, I was using a Sound Blaster and an Ensoniq clone. * they had slightly different start-up latencies (not really audible), * and the Ensoniq's dac was running ca. 1 sample per second faster than * the SB's, so by 5 minutes into a sound, the stereo pairs had drifted * .01 seconds apart -- this is probably acceptable in many cases. * In a second test, with two Ensoniq's in one machine, they started * together and drifted apart at about 1 sample per 8 seconds -- about * .001 secs apart after 5 minutes. ("Ensoniq" was SoundWave Pro PCI * from SIIG Inc -- some sort of clone.) */ buffer_size = 256; /* 128 probably better */ outbytes = buffer_size * 2 * 2; qbufs = (mus_sample_t **)calloc(chans, sizeof(mus_sample_t *)); for (i = 0; i < chans; i++) qbufs[i] = (mus_sample_t *)calloc(buffer_size, sizeof(mus_sample_t)); obuf0 = (short *)calloc(buffer_size * 2, sizeof(short)); obuf1 = (short *)calloc(buffer_size * 2, sizeof(short)); for (m = 0; m < frames; m += buffer_size) { if ((m + buffer_size) <= frames) curframes = buffer_size; else curframes = frames - m; mus_file_read(fd, 0, curframes - 1, chans, qbufs); if (use_volume) set_volume(qbufs, chans, curframes, volume); for (k = 0, n = 0; k < buffer_size; k++, n += 2) { obuf0[n] = MUS_SAMPLE_TO_SHORT(qbufs[0][k]); obuf0[n + 1] = MUS_SAMPLE_TO_SHORT(qbufs[1][k]); obuf1[n] = MUS_SAMPLE_TO_SHORT(qbufs[2][k]); obuf1[n + 1] = MUS_SAMPLE_TO_SHORT(qbufs[3][k]); } if (afd0 == -1) { afd0 = mus_audio_open_output(MUS_AUDIO_PACK_SYSTEM(0) | MUS_AUDIO_DEFAULT, srate, 2, MUS_AUDIO_COMPATIBLE_FORMAT, outbytes); afd1 = mus_audio_open_output(MUS_AUDIO_PACK_SYSTEM(1) | MUS_AUDIO_DEFAULT, srate, 2, MUS_AUDIO_COMPATIBLE_FORMAT, outbytes); if ((afd0 == -1) || (afd1 == -1)) break; } mus_audio_write(afd0, (char *)obuf0, outbytes); mus_audio_write(afd1, (char *)obuf1, outbytes); } mus_audio_close(afd0); mus_audio_close(afd1); mus_sound_close_input(fd); for (i = 0; i < chans; i++) free(qbufs[i]); free(qbufs); free(obuf0); free(obuf1); } } return(0); }
int main(int argc, char *argv[]) { int fd, afd, i, j, n, k, chans, srate; mus_long_t frames, m; mus_sample_t **bufs; OutSample *obuf; int buffer_size = BUFFER_SIZE, curframes, 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_header_type_p(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_data_format_p(mus_sound_data_format(name)))) { fprintf(stderr, "can't play %s (data format: %s (%s)?)\n", name, mus_data_format_name(mus_sound_data_format(name)), mus_header_original_format_name(mus_sound_original_format(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); frames = mus_sound_frames(name); sample_size = mus_bytes_per_sample(MUS_AUDIO_COMPATIBLE_FORMAT); start = (mus_long_t)(begin_time * srate); if (start > 0) mus_file_seek_frame(fd, start); if (end_time > 0.0) end = (mus_long_t)(end_time * srate); else end = frames; if ((end - start) < frames) frames = end - start; bufs = (mus_sample_t **)calloc(chans, sizeof(mus_sample_t *)); for (i = 0; i < chans; i++) bufs[i] = (mus_sample_t *)calloc(buffer_size, sizeof(mus_sample_t)); obuf = (OutSample *)calloc(buffer_size * out_chans, sizeof(OutSample)); outbytes = buffer_size * out_chans * sample_size; for (m = 0; m < frames; m += buffer_size) { if ((m + buffer_size) <= frames) curframes = buffer_size; else curframes = frames - m; mus_file_read(fd, 0, curframes - 1, 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 < curframes; k++) obuf[k] = MUS_CONVERT(bufs[0][k]); } else { if (chans == 2) { for (k = 0, n = 0; k < curframes; 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 < curframes; k++, j += chans) { for (n = 0; n < chans; n++) obuf[j + n] = MUS_CONVERT(bufs[n][k]); } } } #if MUS_MAC_OSX 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_FORMAT, outbytes); if (afd == -1) break; } outbytes = curframes * 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); }