2
* Purpose: Sources for the ossplay audio player and for the ossrecord
3
* audio recorder shipped with OSS.
6
* OSSPlay is a audio file player that supports most commonly used uncompressed
7
* audio formats (.wav, .snd, .au, .aiff). It doesn't play compressed formats
9
* OSSRecord is a simple file recorder. It can write simple file formats
12
* This file contains the audio backend and misc. functions.
14
* This program is bit old and it uses some OSS features that may no longer be
19
* This file is part of Open Sound System.
21
* Copyright (C) 4Front Technologies 1996-2008.
23
* This this source file is released under GPL v2 license (no other versions).
24
* See the COPYING file included in the main directory of this source
25
* distribution for the license terms and conditions.
29
#include "ossplay_decode.h"
30
#include "ossplay_parser.h"
31
#include "ossplay_wparser.h"
37
unsigned int amplification = 100;
38
int eflag = 0, force_speed = 0, force_fmt = 0, force_channels = 0,
39
overwrite = 1, verbose = 0, quiet = 0;
40
flag from_stdin = 0, int_conv = 0, level_meters = 0, loop = 0,
41
raw_file = 0, raw_mode = 0;
44
off_t (*ossplay_lseek) (int, off_t, int) = lseek;
46
char script[512] = "";
47
unsigned int nfiles = 1;
49
fctypes_t type = WAVE_FILE;
51
const format_t format_a[] = {
52
{"S8", AFMT_S8, CRP, AFMT_S16_NE},
53
{"U8", AFMT_U8, CRP, AFMT_S16_NE},
54
{"S16_LE", AFMT_S16_LE, CRP, AFMT_S16_NE},
55
{"S16_BE", AFMT_S16_BE, CRP, AFMT_S16_NE},
56
{"U16_LE", AFMT_U16_LE, CRP, AFMT_S16_NE},
57
{"U16_BE", AFMT_U16_BE, CRP, AFMT_S16_NE},
58
{"S24_LE", AFMT_S24_LE, CRP, 0},
59
{"S24_BE", AFMT_S24_BE, CRP, 0},
60
{"S32_LE", AFMT_S32_LE, CRP, AFMT_S32_NE},
61
{"S32_BE", AFMT_S32_BE, CRP, AFMT_S32_NE},
62
{"A_LAW", AFMT_A_LAW, CRP, AFMT_S16_NE},
63
{"MU_LAW", AFMT_MU_LAW, CRP, AFMT_S16_NE},
64
{"FLOAT32_LE", AFMT_FLOAT32_LE, CP, 0},
65
{"FLOAT32_BE", AFMT_FLOAT32_BE, CP, 0},
66
{"DOUBLE64_LE", AFMT_DOUBLE64_LE, CP, 0},
67
{"DOUBLE64_BE", AFMT_DOUBLE64_BE, CP, 0},
68
{"S24_PACKED", AFMT_S24_PACKED, CRP, 0},
69
{"S24_PACKED_BE", AFMT_S24_PACKED_BE, CP, 0},
70
{"IMA_ADPCM", AFMT_IMA_ADPCM, CP, 0},
71
{"IMA_ADPCM_3BITS", AFMT_MS_IMA_ADPCM_3BITS,CP, 0},
72
{"MS_ADPCM", AFMT_MS_ADPCM, CP, 0},
73
{"CR_ADPCM_2", AFMT_CR_ADPCM_2, CP, 0},
74
{"CR_ADPCM_3", AFMT_CR_ADPCM_3, CP, 0},
75
{"CR_ADPCM_4", AFMT_CR_ADPCM_4, CP, 0},
76
{"SPDIF_RAW", AFMT_SPDIF_RAW, CR, 0},
77
{"FIBO_DELTA", AFMT_FIBO_DELTA, CP, 0},
78
{"EXP_DELTA", AFMT_EXP_DELTA, CP, 0},
82
static const container_t container_a[] = {
83
{"RAW", RAW_FILE, AFMT_S16_LE, 2, 44100},
84
{"WAV", WAVE_FILE, AFMT_S16_LE, 2, 48000},
85
{"AU", AU_FILE, AFMT_MU_LAW, 1, 8000},
86
{"AIFF", AIFF_FILE, AFMT_S16_BE, 2, 48000},
87
{"CAF", CAF_FILE, AFMT_S16_NE, 2, 48000},
88
{NULL, RAW_FILE, 0, 0, 0}
89
}; /* Order should match fctypes_t enum so that container_a[type] works */
91
static void describe_error (void);
92
static void find_devname (char *, const char *);
93
static fctypes_t select_container (const char *);
94
static int select_format (const char *, int);
95
static void ossplay_usage (const char *);
96
static void ossrecord_usage (const char *);
97
static void ossplay_getint (int);
98
static void print_play_verbose_info (const unsigned char *, ssize_t, void *);
99
static void print_record_verbose_info (const unsigned char *, ssize_t, void *);
102
be_int (const unsigned char * p, int l)
109
for (i = 0; i < l; i++)
111
val = (val << 8) | p[i];
118
le_int (const unsigned char * p, int l)
125
for (i = l - 1; i >= 0; i--)
127
val = (val << 8) | p[i];
134
describe_error (void)
140
print_msg (ERRORM, "\nThe device file was found in /dev but\n"
141
"there is no driver for it currently loaded.\n"
143
"You can start it by executing the soundon command as\n"
144
"super user (root).\n");
148
print_msg (ERRORM, "\nThe soundcard driver was not installed\n"
149
"properly. The system is out of DMA compatible memory.\n"
150
"Please reboot your system and try again.\n");
155
print_msg (ERRORM, "\nThe sound device file is missing from /dev.\n"
156
"You should try re-installing OSS.\n");
161
"\nThere is some other application using this audio device.\n"
162
"Exit it and try again.\n");
164
"You can possibly find out the conflicting application by"
166
"at the printout produced by command 'ossinfo -a -v1'\n");
174
find_devname (char * devname, const char * num)
177
* OSS 4.0 the audio device numbering may be different from the
178
* legacy /dev/dsp# numbering reported by /dev/sndstat. Try to find the
179
* device name (devnode) that matches the given device number.
181
* Prior versions of ossplay simply used the the /dev/dsp# number.
186
const char * devmixer;
188
if ((devmixer = getenv("OSS_MIXERDEV")) == NULL)
189
devmixer = "/dev/mixer";
191
if (sscanf (num, "%d", &dev) != 1)
193
print_msg (ERRORM, "Invalid audio device number '%s'\n", num);
194
exit (E_SETUP_ERROR);
197
if ((mixer_fd = open (devmixer, O_RDWR, 0)) == -1)
199
perror_msg (devmixer);
200
print_msg (WARNM, "Warning: Defaulting to /dev/dsp%s\n", num);
201
snprintf (devname, OSS_DEVNODE_SIZE, "/dev/dsp%s", num);
207
if (ioctl (mixer_fd, SNDCTL_AUDIOINFO, &ai) == -1)
209
perror_msg ("SNDCTL_AUDIOINFO");
210
print_msg (WARNM, "Warning: Defaulting to /dev/dsp%s\n", num);
211
snprintf (devname, OSS_DEVNODE_SIZE, "/dev/dsp%s", num);
216
strncpy (devname, ai.devnode, OSS_DEVNODE_SIZE);
223
filepart (const char *name)
225
const char * s = name;
227
if (name == NULL) return "";
231
if (name[0] == '/' && name[1] != '\0')
240
format2bits (int format)
244
case AFMT_CR_ADPCM_2: return 2;
245
case AFMT_CR_ADPCM_3: return 2.6666F;
246
case AFMT_MS_IMA_ADPCM_3BITS: return 3;
247
case AFMT_CR_ADPCM_4:
248
case AFMT_MAC_IMA_ADPCM:
249
case AFMT_MS_IMA_ADPCM:
252
case AFMT_FIBO_DELTA:
253
case AFMT_EXP_DELTA: return 4;
257
case AFMT_S8: return 8;
263
case AFMT_U16_BE: return 16;
264
case AFMT_S24_PACKED:
265
case AFMT_S24_PACKED_BE: return 24;
269
case AFMT_FLOAT32_LE:
270
case AFMT_FLOAT32_BE:
272
case AFMT_S32_BE: return 32;
273
case AFMT_DOUBLE64_LE:
274
case AFMT_DOUBLE64_BE: return 64;
275
case AFMT_FLOAT: return sizeof (float) * 8;
282
close_device (dspdev_t * dsp)
284
if (dsp->fd == -1) return;
290
open_device (dspdev_t * dsp)
297
dsp->format = 0; dsp->channels = 0; dsp->speed = 0;
299
if ((devdsp = getenv("OSS_AUDIODEV")) == NULL)
303
dsp->flags |= O_EXCL; /* Disable redirection to the virtual mixer */
305
if (dsp->dname[0] == '\0') strcpy (dsp->dname, devdsp);
307
if ((dsp->fd = open (dsp->dname, dsp->flags, 0)) == -1)
309
perror_msg (dsp->dname);
311
exit (E_SETUP_ERROR);
317
* Disable sample rate/format conversions.
320
ioctl (dsp->fd, SNDCTL_DSP_COOKEDMODE, &tmp);
325
ossplay_usage (const char * prog)
327
print_msg (HELPM, "Usage: %s [options] filename(s)\n", prog?prog:"ossplay");
328
print_msg (HELPM, " Options: -v Verbose output.\n");
329
print_msg (HELPM, " -q No informative printouts.\n");
330
print_msg (HELPM, " -d<devname> Change output device.\n");
331
print_msg (HELPM, " -g<gain> Change gain.\n");
332
print_msg (HELPM, " -s<rate> Change playback rate.\n");
333
print_msg (HELPM, " -f<fmt>|? Change/Query input format.\n");
334
print_msg (HELPM, " -c<channels> Change number of channels.\n");
335
print_msg (HELPM, " -o<playtgt>|? Select/Query output target.\n");
336
print_msg (HELPM, " -l Loop playback indefinitely.\n");
337
print_msg (HELPM, " -W Treat all input as raw PCM.\n");
338
print_msg (HELPM, " -S<secs> Start playing from offset.\n");
340
" -R Open sound device in raw mode.\n");
345
ossrecord_usage (const char * prog)
347
print_msg (HELPM, "Usage: %s [options] filename\n", prog?prog:"ossrecord");
348
print_msg (HELPM, " Options: -v Verbose output.\n");
349
print_msg (HELPM, " -d<device> Change input device.\n");
350
print_msg (HELPM, " -c<channels> Change number of channels\n");
351
print_msg (HELPM, " -L<level> Change recording level.\n");
353
" -g<gain> Change gain percentage.\n");
354
print_msg (HELPM, " -s<rate> Change recording rate.\n");
355
print_msg (HELPM, " -f<fmt|?> Change/Query sample format.\n");
357
" -F<cnt|?> Change/Query container format.\n");
358
print_msg (HELPM, " -l Display level meters.\n");
360
" -i<recsrc|?> Select/Query recording source.\n");
362
" -m<nfiles> Repeat recording <nfiles> times.\n");
364
" -r<command> Run <command> after recording.\n");
366
" -t<maxsecs> Record no more than <maxsecs> in a"
367
" single recording.\n");
369
" -R Open sound device in raw mode.\n");
370
print_msg (HELPM, " -O Do not allow overwrite.\n");
375
sample_format_name (int sformat)
379
for (i = 0; format_a[i].fmt != 0; i++)
380
if (format_a[i].fmt == sformat)
381
return format_a[i].name;
387
select_container (const char * optstr)
390
* Handling of the -F command line option (force container format).
392
* Empty or "?" shows the supported container format names.
396
if ((!strcmp(optstr, "?")) || (*optstr == '\0'))
398
print_msg (STARTM, "\nSupported container format names are:\n\n");
399
for (i = 0; container_a[i].name != NULL; i++)
400
print_msg (CONTM, "%s ", container_a[i].name);
401
print_msg (ENDM, "\n");
405
for (i = 0; container_a[i].name != NULL; i++)
406
if (!strcasecmp(container_a[i].name, optstr))
407
return container_a[i].type;
409
print_msg (ERRORM, "Unsupported container format name '%s'!\n", optstr);
414
select_format (const char * optstr, int dir)
417
* Handling of the -f command line option (force input format).
419
* Empty or "?" shows the supported format names.
423
if ((!strcmp(optstr, "?")) || (*optstr == '\0'))
425
print_msg (STARTM, "\nSupported format names are:\n\n");
426
for (i = 0; format_a[i].name != NULL; i++)
427
if (dir & format_a[i].dir)
428
print_msg (CONTM, "%s ", format_a[i].name);
429
print_msg (ENDM, "\n");
433
for (i = 0; format_a[i].name != NULL; i++)
434
if ((format_a[i].dir & dir) && (!strcasecmp(format_a[i].name, optstr)))
435
return format_a[i].fmt;
437
print_msg (ERRORM, "Unsupported format name '%s'!\n", optstr);
442
select_playtgt (dspdev_t * dsp)
445
* Handling of the -o command line option (playback target selection).
447
* Empty or "?" shows the available playback sources.
450
oss_mixer_enuminfo ei;
452
if (ioctl (dsp->fd, SNDCTL_DSP_GET_PLAYTGT_NAMES, &ei) == -1)
454
perror_msg ("SNDCTL_DSP_GET_PLAYTGT_NAMES");
455
exit (E_SETUP_ERROR);
458
if (ioctl (dsp->fd, SNDCTL_DSP_GET_PLAYTGT, &src) == -1)
460
perror_msg ("SNDCTL_DSP_GET_PLAYTGT");
461
exit (E_SETUP_ERROR);
464
if ((dsp->playtgt[0] == '\0') || (strcmp (dsp->playtgt, "?") == 0))
467
"\nPossible playback targets for the selected device:\n\n");
469
for (i = 0; i < ei.nvalues; i++)
471
print_msg (CONTM, "\t%s", ei.strings + ei.strindex[i]);
473
print_msg (CONTM, " (currently selected)");
474
print_msg (CONTM, "\n");
476
print_msg (ENDM, "\n");
480
for (i = 0; i < ei.nvalues; i++)
482
char *s = ei.strings + ei.strindex[i];
483
if (strcmp (s, dsp->playtgt) == 0)
486
if (ioctl (dsp->fd, SNDCTL_DSP_SET_PLAYTGT, &src) == -1)
488
perror_msg ("SNDCTL_DSP_SET_PLAYTGT");
489
exit (E_SETUP_ERROR);
497
"Unknown playback target name '%s' - use -o? to get the list\n",
503
select_recsrc (dspdev_t * dsp)
506
* Handling of the -i command line option (recording source selection).
508
* Empty or "?" shows the available recording sources.
511
oss_mixer_enuminfo ei;
513
if (ioctl (dsp->fd, SNDCTL_DSP_GET_RECSRC_NAMES, &ei) == -1)
515
perror_msg ("SNDCTL_DSP_GET_RECSRC_NAMES");
516
exit (E_SETUP_ERROR);
519
if (ioctl (dsp->fd, SNDCTL_DSP_GET_RECSRC, &src) == -1)
521
perror_msg ("SNDCTL_DSP_GET_RECSRC");
522
exit (E_SETUP_ERROR);
525
if (dsp->recsrc[0] == '\0' || strcmp (dsp->recsrc, "?") == 0)
528
"\nPossible recording sources for the selected device:\n\n");
530
for (i = 0; i < ei.nvalues; i++)
532
print_msg (CONTM, "\t%s", ei.strings + ei.strindex[i]);
534
print_msg (CONTM, " (currently selected)");
535
print_msg (CONTM, "\n");
537
print_msg (ENDM, "\n");
541
for (i = 0; i < ei.nvalues; i++)
543
char *s = ei.strings + ei.strindex[i];
544
if (strcmp (s, dsp->recsrc) == 0)
547
if (ioctl (dsp->fd, SNDCTL_DSP_SET_RECSRC, &src) == -1)
549
perror_msg ("SNDCTL_DSP_SET_RECSRC");
550
exit (E_SETUP_ERROR);
557
"Unknown recording source name '%s' - use -i? to get the list\n",
563
setup_device (dspdev_t * dsp, int format, int channels, int speed)
567
if (dsp->speed != speed || dsp->format != format ||
568
dsp->channels != channels || dsp->fd == -1)
571
ioctl (dsp->fd, SNDCTL_DSP_SYNC, NULL);
572
ioctl (dsp->fd, SNDCTL_DSP_HALT, NULL);
576
if (dsp->playtgt != NULL) select_playtgt (dsp);
577
if (dsp->recsrc != NULL) select_recsrc (dsp);
582
ioctl (dsp->fd, SNDCTL_SETSONG, dsp->current_songname);
587
* Report the current filename as the song name.
589
ioctl (dsp->fd, SNDCTL_SETSONG, dsp->current_songname);
592
ioctl (dsp->fd, SNDCTL_DSP_PROFILE, &tmp);
596
if (ioctl (dsp->fd, SNDCTL_DSP_SETFMT, &tmp) == -1)
598
perror_msg (dsp->dname);
599
print_msg (ERRORM, "Failed to select bits/sample\n");
600
return E_SETUP_ERROR;
605
print_msg (ERRORM, "%s doesn't support this audio format (%x/%x).\n",
606
dsp->dname, format, tmp);
607
return E_FORMAT_UNSUPPORTED;
612
if (ioctl (dsp->fd, SNDCTL_DSP_CHANNELS, &tmp) == -1)
614
perror_msg (dsp->dname);
615
print_msg (ERRORM, "Failed to select number of channels.\n");
616
return E_SETUP_ERROR;
622
/* We'll convert mono to stereo, so it's no use warning */
623
if ((channels != 1) || (tmp != 2))
625
print_msg (ERRORM, "%s doesn't support %d channels (%d).\n",
626
dsp->dname, channels, tmp);
627
return E_CHANNELS_UNSUPPORTED;
632
if (ioctl (dsp->fd, SNDCTL_DSP_SPEED, &tmp) == -1)
634
perror_msg (dsp->dname);
635
print_msg (ERRORM, "Failed to select sampling rate.\n");
636
return E_SETUP_ERROR;
642
print_msg (WARNM, "Warning: Playback using %d Hz (file %d Hz)\n",
648
dsp->channels = channels;
649
dsp->format = format;
652
print_msg (VERBOSEM, "Setup device %s/%d/%d\n",
653
sample_format_name (dsp->format), dsp->channels, dsp->speed);
655
if (dsp->reclevel != 0)
657
tmp = dsp->reclevel | (dsp->reclevel << 8);
659
if (ioctl (dsp->fd, SNDCTL_DSP_SETRECVOL, &tmp) == -1)
660
perror ("SNDCTL_DSP_SETRECVOL");
667
ossplay_getint (int signum)
670
if (eflag == signum + 128)
672
signal (signum, SIG_DFL);
673
kill (getpid(), signum);
676
eflag = signum + 128;
680
ossplay_parse_opts (int argc, char ** argv, dspdev_t * dsp)
682
extern char * optarg;
687
while ((c = getopt (argc, argv, "FRS:Wc:d:f:g:hlo:qs:v")) != EOF)
704
if (int_conv == 2) int_conv = 0;
708
if (*optarg >= '0' && *optarg <= '9') /* Only device number given */
709
find_devname (dsp->dname, optarg);
711
snprintf (dsp->dname, OSS_DEVNODE_SIZE, "%s", optarg);
715
if (!strcmp(optarg, "?"))
717
dsp->playtgt = optarg;
718
dsp->flags = O_WRONLY;
720
select_playtgt (dsp);
722
dsp->playtgt = optarg;
726
force_fmt = select_format (optarg, CP);
730
sscanf (optarg, "%d", &force_speed);
734
sscanf (optarg, "%d", &force_channels);
738
sscanf (optarg, "%u", &lification);
753
if ((c > 0) && ((optarg[c - 1] == 'b') || (optarg[c - 1] == 'B')))
756
seek_byte = strtol (optarg, &p, 10);
757
if ((*p != '\0') || (seek_byte < 0)) ossplay_usage (argv[0]);
762
seek_time = strtod (optarg, &p);
763
if ((*p != '\0') || (errno) || (seek_time < 0)) ossplay_usage (argv[0]);
768
ossplay_usage (argv[0]);
773
if (argc < optind + 1)
774
ossplay_usage (argv[0]);
777
signal (SIGQUIT, ossplay_getint);
783
ossrecord_parse_opts (int argc, char ** argv, dspdev_t * dsp)
786
extern char * optarg;
790
ossrecord_usage (argv[0]);
792
while ((c = getopt (argc, argv, "F:L:MORSb:c:d:f:g:hi:lm:r:s:t:wv")) != EOF)
796
type = select_container (optarg);
800
dsp->reclevel = atoi (optarg);
801
if (dsp->reclevel < 1 || dsp->reclevel > 100)
803
print_msg (ERRORM, "%s: Bad recording level '%s'\n",
804
argv[0]?argv[0]:"", optarg);
823
c += c % 8; /* Simple WAV format always pads to a multiple of 8 */
826
case 8: force_fmt = AFMT_U8; break;
827
case 16: force_fmt = AFMT_S16_LE; break;
828
case 24: force_fmt = AFMT_S24_PACKED; break;
829
case 32: force_fmt = AFMT_S32_LE; break;
831
print_msg (ERRORM, "Error: Unsupported number of bits %d\n", c);
832
exit (E_FORMAT_UNSUPPORTED);
837
sscanf (optarg, "%d", &force_channels);
841
if (*optarg >= '0' && *optarg <= '9') /* Only device number given */
842
find_devname (dsp->dname, optarg);
844
snprintf (dsp->dname, OSS_DEVNODE_SIZE, "%s", optarg);
848
force_fmt = select_format (optarg, CR);
852
sscanf (optarg, "%u", &lification);
853
if (amplification == 0) ossrecord_usage (argv[0]);
861
if (!strcmp(optarg, "?"))
863
dsp->recsrc = optarg;
864
dsp->flags = O_RDONLY;
868
dsp->recsrc = optarg;
872
sscanf (optarg, "%u", &nfiles);
876
sscanf (optarg, "%d", &force_speed);
877
if (force_speed == 0)
879
print_msg (ERRORM, "Bad sampling rate given\n");
882
if (force_speed < 1000) force_speed *= 1000;
886
c = snprintf (script, sizeof (script), "%s", optarg);
887
if (((size_t)c >= sizeof (script)) || (c < 0))
889
print_msg (ERRORM, "-r argument is too long!\n");
895
sscanf (optarg, _PRIbig_t, &datalimit);
911
ossrecord_usage (argv[0]);
914
if (argc != optind + 1)
915
/* No file or multiple file names given */
916
ossrecord_usage (argv[0]);
918
if (force_fmt == 0) force_fmt = container_a[type].dformat;
919
if (force_channels == 0) force_channels = container_a[type].dchannels;
920
if (force_speed == 0) force_speed = container_a[type].dspeed;
927
case AFMT_S32_NE: break;
928
default: level_meters = 0; /* Not implemented */
931
if ((signal (SIGSEGV, ossplay_getint) == SIG_ERR) ||
933
(signal (SIGPIPE, ossplay_getint) == SIG_ERR) ||
935
(signal (SIGTERM, ossplay_getint) == SIG_ERR) ||
937
(signal (SIGQUIT, ossplay_getint) == SIG_ERR) ||
939
(signal (SIGINT, ossplay_getint) == SIG_ERR))
940
print_msg (WARNM, "Signal handler not set up!\n");
948
if (ioctl(dsp->fd, SNDCTL_ENGINEINFO, &ai) != -1)
949
print_msg (VERBOSEM, "Recording from %s\n", ai.name);
956
ossplay_ldexpl (ldouble_t num, int exp)
959
* Very simple emulation of ldexpl to avoid linking to libm or assuming
960
* anything about float representation.
985
print_play_verbose_info (const unsigned char * buf, ssize_t l, void * metadata)
988
* Display a rough recording level meter, and the elapsed time.
991
verbose_values_t * val = (verbose_values_t *)metadata;
993
val->secs += l/val->constant;
994
if (val->secs < val->next_sec) return;
995
val->next_sec += PLAY_UPDATE_INTERVAL/1000;
997
* This check is done to ensure an update at the end of the playback.
998
* Note that some files lie about total time, so the second condition is
999
* necessary so that updates will still be constricted by PLAY_UPDATE_INTERVAL.
1001
if ((val->next_sec > val->tsecs) && (val->secs < val->tsecs)) val->next_sec = val->tsecs;
1003
print_update (get_db_level (buf, l, val->format), val->secs, val->tstring);
1009
print_record_verbose_info (const unsigned char * buf, ssize_t l,
1013
* Display a rough recording level meter if enabled, and the elapsed time.
1016
verbose_values_t * val = (verbose_values_t *)metadata;
1017
int update_dots = 1;
1019
val->secs += l / val->constant;
1021
if (val->secs >= val->next_sec)
1023
val->next_sec += REC_UPDATE_INTERVAL/1000;
1024
if ((val->tsecs) && (val->next_sec > val->tsecs))
1025
val->next_sec = val->tsecs;
1028
val->secs_timer2 = val->next_sec_timer2 = val->secs;
1031
print_record_update (-1, val->secs, val->tstring, 1);
1033
else if ((level_meters) && (val->secs >= val->next_sec_timer2))
1037
val->next_sec_timer2 += LMETER_UPDATE_INTERVAL/1000;
1038
if ((val->tsecs) && (val->next_sec_timer2 > val->tsecs))
1039
val->next_sec_timer2 = val->tsecs;
1040
print_record_update (get_db_level (buf, l, val->format), val->secs_timer2,
1041
val->tstring, update_dots);
1046
play (dspdev_t * dsp, int fd, big_t * datamark, big_t bsize, double total_time,
1047
double constant, readfunc_t * readf, decoders_queue_t * dec, seekfunc_t * seekf)
1049
#define EXITPLAY(code) \
1051
ossplay_free (buf); \
1052
ossplay_free (verbose_meta); \
1054
ioctl (dsp->fd, SNDCTL_DSP_HALT_OUTPUT, NULL); \
1059
big_t rsize = bsize;
1060
big_t filesize = *datamark;
1062
unsigned char * buf, * obuf, contflag = 0;
1063
decoders_queue_t * d;
1064
verbose_values_t * verbose_meta = NULL;
1066
buf = (unsigned char *)ossplay_malloc (bsize);
1070
verbose_meta = setup_verbose (dsp->format,
1071
format2bits(dsp->format) * dsp->channels *
1072
dsp->speed / 8.0, total_time);
1073
if (seek_time == 0) print_play_verbose_info (NULL, 0, verbose_meta);
1078
while (*datamark < filesize)
1080
if (eflag) EXITPLAY (eflag);
1083
if (rsize > filesize - *datamark) rsize = filesize - *datamark;
1085
if ((seek_time != 0) && (seekf != NULL))
1089
ret = seekf (fd, datamark, filesize, constant, rsize, dsp->channels,
1095
verbose_meta->secs = (double)seek_time;
1096
verbose_meta->next_sec = (double)seek_time;
1097
print_play_verbose_info (NULL, 0, verbose_meta);
1102
else if (ret == SEEK_CONT_AFTER_DECODE) contflag = 1;
1103
else EXITPLAY (ret);
1106
if ((outl = readf (fd, buf, rsize, dec->metadata)) <= 0)
1108
if (errno) perror_msg ("read");
1109
if ((filesize != BIG_SPECIAL) && (*datamark < filesize) && (!eflag))
1111
print_msg (NOTIFYM, "Sound data ended prematurely!\n");
1123
obuf = buf; d = dec;
1126
outl = d->decoder (&(d->outbuf), obuf, outl, d->metadata);
1132
if (verbose) print_play_verbose_info (obuf, outl, verbose_meta);
1133
if (write (dsp->fd, obuf, outl) == -1)
1135
if ((errno == EINTR) && (eflag)) EXITPLAY (eflag);
1137
perror_msg ("audio write");
1143
ossplay_free (verbose_meta);
1149
record (dspdev_t * dsp, FILE * wave_fp, const char * filename, double constant,
1150
big_t datalimit, big_t * data_size, decoders_queue_t * dec)
1152
#define EXITREC(code) \
1154
ossplay_free (buf); \
1155
ossplay_free (verbose_meta); \
1157
if ((eflag) && (verbose)) \
1158
print_msg (VERBOSEM, "\nStopped (%d).\n", eflag-128); \
1159
ioctl (dsp->fd, SNDCTL_DSP_HALT_INPUT, NULL); \
1164
decoders_queue_t * d;
1165
unsigned char * buf, * obuf;
1166
verbose_values_t * verbose_meta = NULL;
1170
verbose_meta = setup_verbose (dsp->format, constant, datalimit/constant);
1171
strncpy (verbose_meta->tstring, filename, 20)[19] = 0;
1175
buf = (unsigned char *)ossplay_malloc (RECBUF_SIZE);
1176
/*LINTED*/ while (1)
1178
if ((l = read (dsp->fd, buf, RECBUF_SIZE)) < 0)
1180
if ((errno == EINTR) && (eflag)) EXITREC (eflag);
1181
if (errno == ECONNRESET) EXITREC (E_ENCODE); /* Device disconnected */
1182
perror_msg (dsp->dname);
1187
print_msg (ERRORM, "Unexpected EOF on audio device\n");
1191
obuf = buf; d = dec; outl = l;
1194
outl = d->decoder (&(d->outbuf), obuf, outl, d->metadata);
1200
if (eflag) EXITREC (eflag);
1202
if (fwrite (obuf, outl, 1, wave_fp) != 1)
1204
if ((errno == EINTR) && (eflag)) EXITREC (eflag);
1205
perror_msg (filename);
1210
if (verbose) print_record_verbose_info (obuf, outl, verbose_meta);
1212
if ((datalimit != 0) && (*data_size >= datalimit)) break;
1216
ossplay_free (verbose_meta);
1218
print_msg (VERBOSEM, "\nDone.\n");
1223
silence (dspdev_t * dsp, big_t len, int speed)
1227
unsigned char empty[1024];
1229
ret = setup_device (dsp, AFMT_U8, 1, speed);
1231
if (ret == E_FORMAT_UNSUPPORTED)
1234
if ((ret = setup_device (dsp, AFMT_S16_NE, 2, speed))) return ret;
1236
else if (ret) return ret;
1238
memset (empty, 0, 1024 * sizeof (unsigned char));
1243
if ((big_t)i > len) i = len;
1244
if ((i = write (dsp->fd, empty, i)) < 0) return -1;