aiff: handle id3 tags
[sox.git] / src / dat.c
blobb014f23499311eda31fadc9edea11630eb7a7216
1 /* libSoX text format file. Tom Littlejohn, March 93.
3 * Reads/writes sound files as text.
5 * Copyright 1998-2006 Chris Bagwell and SoX Contributors
6 * This source code is freely redistributable and may be used for
7 * any purpose. This copyright notice must be maintained.
8 * Lance Norskog And Sundry Contributors are not responsible for
9 * the consequences of using this software.
12 #include "sox_i.h"
13 #include <string.h>
15 #define LINEWIDTH (size_t)256
17 /* Private data for dat file */
18 typedef struct {
19 double timevalue, deltat;
20 int buffered;
21 char prevline[LINEWIDTH];
22 } priv_t;
24 static int sox_datstartread(sox_format_t * ft)
26 char inpstr[LINEWIDTH];
27 long rate;
28 int chan;
29 int status;
30 char sc;
32 /* Read lines until EOF or first non-comment line */
33 while ((status = lsx_reads(ft, inpstr, LINEWIDTH-1)) != SOX_EOF) {
34 inpstr[LINEWIDTH-1] = 0;
35 if ((sscanf(inpstr," %c", &sc) != 0) && (sc != ';')) break;
36 if (sscanf(inpstr," ; Sample Rate %ld", &rate)) {
37 ft->signal.rate=rate;
38 } else if (sscanf(inpstr," ; Channels %d", &chan)) {
39 ft->signal.channels=chan;
42 /* Hold a copy of the last line we read (first non-comment) */
43 if (status != SOX_EOF) {
44 strncpy(((priv_t *)ft->priv)->prevline, inpstr, (size_t)LINEWIDTH);
45 ((priv_t *)ft->priv)->buffered = 1;
46 } else {
47 ((priv_t *)ft->priv)->buffered = 0;
50 /* Default channels to 1 if not found */
51 if (ft->signal.channels == 0)
52 ft->signal.channels = 1;
54 ft->encoding.encoding = SOX_ENCODING_FLOAT_TEXT;
56 return (SOX_SUCCESS);
59 static int sox_datstartwrite(sox_format_t * ft)
61 priv_t * dat = (priv_t *) ft->priv;
62 char s[LINEWIDTH];
64 dat->timevalue = 0.0;
65 dat->deltat = 1.0 / (double)ft->signal.rate;
66 /* Write format comments to start of file */
67 sprintf(s,"; Sample Rate %ld\015\n", (long)ft->signal.rate);
68 lsx_writes(ft, s);
69 sprintf(s,"; Channels %d\015\n", (int)ft->signal.channels);
70 lsx_writes(ft, s);
72 return (SOX_SUCCESS);
75 static size_t sox_datread(sox_format_t * ft, sox_sample_t *buf, size_t nsamp)
77 char inpstr[LINEWIDTH];
78 int inpPtr = 0;
79 int inpPtrInc = 0;
80 double sampval = 0.0;
81 int retc = 0;
82 char sc = 0;
83 size_t done = 0;
84 size_t i=0;
86 /* Always read a complete set of channels */
87 nsamp -= (nsamp % ft->signal.channels);
89 while (done < nsamp) {
91 /* Read a line or grab the buffered first line */
92 if (((priv_t *)ft->priv)->buffered) {
93 strncpy(inpstr, ((priv_t *)ft->priv)->prevline, (size_t)LINEWIDTH);
94 inpstr[LINEWIDTH-1] = 0;
95 ((priv_t *)ft->priv)->buffered=0;
96 } else {
97 lsx_reads(ft, inpstr, LINEWIDTH-1);
98 inpstr[LINEWIDTH-1] = 0;
99 if (lsx_eof(ft)) return (done);
102 /* Skip over comments - ie. 0 or more whitespace, then ';' */
103 if ((sscanf(inpstr," %c", &sc) != 0) && (sc==';')) continue;
105 /* Read a complete set of channels */
106 sscanf(inpstr," %*s%n", &inpPtr);
107 for (i=0; i<ft->signal.channels; i++) {
108 SOX_SAMPLE_LOCALS;
109 retc = sscanf(&inpstr[inpPtr]," %lg%n", &sampval, &inpPtrInc);
110 inpPtr += inpPtrInc;
111 if (retc != 1) {
112 lsx_fail_errno(ft,SOX_EOF,"Unable to read sample.");
113 return 0;
115 *buf++ = SOX_FLOAT_64BIT_TO_SAMPLE(sampval, ft->clips);
116 done++;
120 return (done);
123 static size_t sox_datwrite(sox_format_t * ft, const sox_sample_t *buf, size_t nsamp)
125 priv_t * dat = (priv_t *) ft->priv;
126 size_t done = 0;
127 double sampval=0.0;
128 char s[LINEWIDTH];
129 size_t i=0;
131 /* Always write a complete set of channels */
132 nsamp -= (nsamp % ft->signal.channels);
134 /* Write time, then sample values, then CRLF newline */
135 while(done < nsamp) {
136 sprintf(s," %15.8g ",dat->timevalue);
137 lsx_writes(ft, s);
138 for (i=0; i<ft->signal.channels; i++) {
139 sampval = SOX_SAMPLE_TO_FLOAT_64BIT(*buf++, ft->clips);
140 sprintf(s," %15.11g", sampval);
141 lsx_writes(ft, s);
142 done++;
144 sprintf(s," \r\n");
145 lsx_writes(ft, s);
146 dat->timevalue += dat->deltat;
148 return done;
151 LSX_FORMAT_HANDLER(dat)
153 static char const * const names[] = {"dat", NULL};
154 static unsigned const write_encodings[] = {SOX_ENCODING_FLOAT_TEXT, 0, 0};
155 static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
156 "Textual representation of the sampled audio", names, 0,
157 sox_datstartread, sox_datread, NULL,
158 sox_datstartwrite, sox_datwrite, NULL,
159 NULL, write_encodings, NULL, sizeof(priv_t)
161 return &handler;