3 * Copyright 1991-2007 Lance Norskog And Sundry Contributors
4 * This source code is freely redistributable and may be used for
5 * any purpose. This copyright notice must be maintained.
6 * Lance Norskog And Sundry Contributors are not responsible for
7 * the consequences of using this software.
13 typedef sox_uint16_t sox_uint14_t
;
14 typedef sox_uint16_t sox_uint13_t
;
15 typedef sox_int16_t sox_int14_t
;
16 typedef sox_int16_t sox_int13_t
;
17 #define SOX_ULAW_BYTE_TO_SAMPLE(d,clips) SOX_SIGNED_16BIT_TO_SAMPLE(sox_ulaw2linear16(d),clips)
18 #define SOX_ALAW_BYTE_TO_SAMPLE(d,clips) SOX_SIGNED_16BIT_TO_SAMPLE(sox_alaw2linear16(d),clips)
19 #define SOX_SAMPLE_TO_ULAW_BYTE(d,c) sox_14linear2ulaw(SOX_SAMPLE_TO_UNSIGNED(14,d,c) - 0x2000)
20 #define SOX_SAMPLE_TO_ALAW_BYTE(d,c) sox_13linear2alaw(SOX_SAMPLE_TO_UNSIGNED(13,d,c) - 0x1000)
22 int lsx_rawseek(sox_format_t
* ft
, uint64_t offset
)
24 return lsx_offset_seek(ft
, (off_t
)ft
->data_start
, (off_t
)offset
);
27 /* Works nicely for starting read and write; lsx_rawstart{read,write}
28 * are #defined in sox_i.h */
29 int lsx_rawstart(sox_format_t
* ft
, sox_bool default_rate
,
30 sox_bool default_channels
, sox_bool default_length
,
31 sox_encoding_t encoding
, unsigned size
)
33 if (default_rate
&& ft
->signal
.rate
== 0) {
34 lsx_warn("`%s': sample rate not specified; trying 8kHz", ft
->filename
);
35 ft
->signal
.rate
= 8000;
38 if (default_channels
&& ft
->signal
.channels
== 0) {
39 lsx_warn("`%s': # channels not specified; trying mono", ft
->filename
);
40 ft
->signal
.channels
= 1;
43 if (encoding
!= SOX_ENCODING_UNKNOWN
) {
44 if (ft
->mode
== 'r' && ft
->encoding
.encoding
!= SOX_ENCODING_UNKNOWN
&&
45 ft
->encoding
.encoding
!= encoding
)
46 lsx_report("`%s': Format options overriding file-type encoding",
49 ft
->encoding
.encoding
= encoding
;
53 if (ft
->mode
== 'r' && ft
->encoding
.bits_per_sample
!= 0 &&
54 ft
->encoding
.bits_per_sample
!= size
)
55 lsx_report("`%s': Format options overriding file-type sample-size",
58 ft
->encoding
.bits_per_sample
= size
;
61 if (!ft
->signal
.length
&& ft
->mode
== 'r' && default_length
&&
62 ft
->encoding
.bits_per_sample
)
64 div_bits(lsx_filelength(ft
), ft
->encoding
.bits_per_sample
);
69 #define READ_SAMPLES_FUNC(type, size, sign, ctype, uctype, cast) \
70 static size_t sox_read_ ## sign ## type ## _samples( \
71 sox_format_t * ft, sox_sample_t *buf, size_t len) \
75 ctype *data = lsx_malloc(sizeof(ctype) * len); \
76 LSX_USE_VAR(sox_macro_temp_sample), LSX_USE_VAR(sox_macro_temp_double); \
77 nread = lsx_read_ ## type ## _buf(ft, (uctype *)data, len); \
78 for (n = 0; n < nread; n++) \
79 *buf++ = cast(data[n], ft->clips); \
84 READ_SAMPLES_FUNC(b
, 1, u
, uint8_t, uint8_t, SOX_UNSIGNED_8BIT_TO_SAMPLE
)
85 READ_SAMPLES_FUNC(b
, 1, s
, int8_t, uint8_t, SOX_SIGNED_8BIT_TO_SAMPLE
)
86 READ_SAMPLES_FUNC(b
, 1, ulaw
, uint8_t, uint8_t, SOX_ULAW_BYTE_TO_SAMPLE
)
87 READ_SAMPLES_FUNC(b
, 1, alaw
, uint8_t, uint8_t, SOX_ALAW_BYTE_TO_SAMPLE
)
88 READ_SAMPLES_FUNC(w
, 2, u
, uint16_t, uint16_t, SOX_UNSIGNED_16BIT_TO_SAMPLE
)
89 READ_SAMPLES_FUNC(w
, 2, s
, int16_t, uint16_t, SOX_SIGNED_16BIT_TO_SAMPLE
)
90 READ_SAMPLES_FUNC(3, 3, u
, sox_uint24_t
, sox_uint24_t
, SOX_UNSIGNED_24BIT_TO_SAMPLE
)
91 READ_SAMPLES_FUNC(3, 3, s
, sox_int24_t
, sox_uint24_t
, SOX_SIGNED_24BIT_TO_SAMPLE
)
92 READ_SAMPLES_FUNC(dw
, 4, u
, uint32_t, uint32_t, SOX_UNSIGNED_32BIT_TO_SAMPLE
)
93 READ_SAMPLES_FUNC(dw
, 4, s
, int32_t, uint32_t, SOX_SIGNED_32BIT_TO_SAMPLE
)
94 READ_SAMPLES_FUNC(f
, sizeof(float), su
, float, float, SOX_FLOAT_32BIT_TO_SAMPLE
)
95 READ_SAMPLES_FUNC(df
, sizeof(double), su
, double, double, SOX_FLOAT_64BIT_TO_SAMPLE
)
97 #define WRITE_SAMPLES_FUNC(type, size, sign, ctype, uctype, cast) \
98 static size_t sox_write_ ## sign ## type ## _samples( \
99 sox_format_t * ft, sox_sample_t const * buf, size_t len) \
102 size_t n, nwritten; \
103 ctype *data = lsx_malloc(sizeof(ctype) * len); \
104 LSX_USE_VAR(sox_macro_temp_sample), LSX_USE_VAR(sox_macro_temp_double); \
105 for (n = 0; n < len; n++) \
106 data[n] = cast(buf[n], ft->clips); \
107 nwritten = lsx_write_ ## type ## _buf(ft, (uctype *)data, len); \
113 WRITE_SAMPLES_FUNC(b
, 1, u
, uint8_t, uint8_t, SOX_SAMPLE_TO_UNSIGNED_8BIT
)
114 WRITE_SAMPLES_FUNC(b
, 1, s
, int8_t, uint8_t, SOX_SAMPLE_TO_SIGNED_8BIT
)
115 WRITE_SAMPLES_FUNC(b
, 1, ulaw
, uint8_t, uint8_t, SOX_SAMPLE_TO_ULAW_BYTE
)
116 WRITE_SAMPLES_FUNC(b
, 1, alaw
, uint8_t, uint8_t, SOX_SAMPLE_TO_ALAW_BYTE
)
117 WRITE_SAMPLES_FUNC(w
, 2, u
, uint16_t, uint16_t, SOX_SAMPLE_TO_UNSIGNED_16BIT
)
118 WRITE_SAMPLES_FUNC(w
, 2, s
, int16_t, uint16_t, SOX_SAMPLE_TO_SIGNED_16BIT
)
119 WRITE_SAMPLES_FUNC(3, 3, u
, sox_uint24_t
, sox_uint24_t
, SOX_SAMPLE_TO_UNSIGNED_24BIT
)
120 WRITE_SAMPLES_FUNC(3, 3, s
, sox_int24_t
, sox_uint24_t
, SOX_SAMPLE_TO_SIGNED_24BIT
)
121 WRITE_SAMPLES_FUNC(dw
, 4, u
, uint32_t, uint32_t, SOX_SAMPLE_TO_UNSIGNED_32BIT
)
122 WRITE_SAMPLES_FUNC(dw
, 4, s
, int32_t, uint32_t, SOX_SAMPLE_TO_SIGNED_32BIT
)
123 WRITE_SAMPLES_FUNC(f
, sizeof(float), su
, float, float, SOX_SAMPLE_TO_FLOAT_32BIT
)
124 WRITE_SAMPLES_FUNC(df
, sizeof (double), su
, double, double, SOX_SAMPLE_TO_FLOAT_64BIT
)
126 #define GET_FORMAT(type) \
127 static ft_##type##_fn * type##_fn(sox_format_t * ft) { \
128 switch (ft->encoding.bits_per_sample) { \
130 switch (ft->encoding.encoding) { \
131 case SOX_ENCODING_SIGN2: return sox_##type##_sb_samples; \
132 case SOX_ENCODING_UNSIGNED: return sox_##type##_ub_samples; \
133 case SOX_ENCODING_ULAW: return sox_##type##_ulawb_samples; \
134 case SOX_ENCODING_ALAW: return sox_##type##_alawb_samples; \
138 switch (ft->encoding.encoding) { \
139 case SOX_ENCODING_SIGN2: return sox_##type##_sw_samples; \
140 case SOX_ENCODING_UNSIGNED: return sox_##type##_uw_samples; \
144 switch (ft->encoding.encoding) { \
145 case SOX_ENCODING_SIGN2: return sox_##type##_s3_samples; \
146 case SOX_ENCODING_UNSIGNED: return sox_##type##_u3_samples; \
150 switch (ft->encoding.encoding) { \
151 case SOX_ENCODING_SIGN2: return sox_##type##_sdw_samples; \
152 case SOX_ENCODING_UNSIGNED: return sox_##type##_udw_samples; \
153 case SOX_ENCODING_FLOAT: return sox_##type##_suf_samples; \
157 switch (ft->encoding.encoding) { \
158 case SOX_ENCODING_FLOAT: return sox_##type##_sudf_samples; \
162 lsx_fail_errno(ft, SOX_EFMT, "this handler does not support this data size"); \
164 lsx_fail_errno(ft, SOX_EFMT, "this encoding is not supported for this data size"); \
167 typedef size_t(ft_read_fn
)
168 (sox_format_t
* ft
, sox_sample_t
* buf
, size_t len
);
172 /* Read a stream of some type into SoX's internal buffer format. */
173 size_t lsx_rawread(sox_format_t
* ft
, sox_sample_t
* buf
, size_t nsamp
)
175 ft_read_fn
* read_buf
= read_fn(ft
);
177 if (read_buf
&& nsamp
)
178 return read_buf(ft
, buf
, nsamp
);
182 typedef size_t(ft_write_fn
)
183 (sox_format_t
* ft
, sox_sample_t
const * buf
, size_t len
);
187 /* Writes SoX's internal buffer format to buffer of various data types. */
189 sox_format_t
* ft
, sox_sample_t
const * buf
, size_t nsamp
)
191 ft_write_fn
* write_buf
= write_fn(ft
);
193 if (write_buf
&& nsamp
)
194 return write_buf(ft
, buf
, nsamp
);