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.
15 #define LINEWIDTH (size_t)256
17 /* Private data for dat file */
19 double timevalue
, deltat
;
21 char prevline
[LINEWIDTH
];
24 static int sox_datstartread(sox_format_t
* ft
)
26 char inpstr
[LINEWIDTH
];
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
)) {
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;
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
;
59 static int sox_datstartwrite(sox_format_t
* ft
)
61 priv_t
* dat
= (priv_t
*) ft
->priv
;
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
);
69 sprintf(s
,"; Channels %d\015\n", (int)ft
->signal
.channels
);
75 static size_t sox_datread(sox_format_t
* ft
, sox_sample_t
*buf
, size_t nsamp
)
77 char inpstr
[LINEWIDTH
];
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;
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
++) {
109 retc
= sscanf(&inpstr
[inpPtr
]," %lg%n", &sampval
, &inpPtrInc
);
112 lsx_fail_errno(ft
,SOX_EOF
,"Unable to read sample.");
115 *buf
++ = SOX_FLOAT_64BIT_TO_SAMPLE(sampval
, ft
->clips
);
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
;
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
);
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
);
146 dat
->timevalue
+= dat
->deltat
;
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
)