1 /* libSoX lpc-10 format.
3 * Copyright 2007 Reuben Thomas <rrt@sc3d.org>
5 * This library is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation; either version 2.1 of the License, or (at
8 * your option) any later version.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
13 * General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "../lpc10/lpc10.h"
30 struct lpc10_encoder_state
*encst
;
31 float speech
[LPC10_SAMPLES_PER_FRAME
];
33 struct lpc10_decoder_state
*decst
;
37 Write the bits in bits[0] through bits[len-1] to file f, in "packed"
40 bits is expected to be an array of len integer values, where each
41 integer is 0 to represent a 0 bit, and any other value represents a
42 1 bit. This bit string is written to the file f in the form of
43 several 8 bit characters. If len is not a multiple of 8, then the
44 last character is padded with 0 bits -- the padding is in the least
45 significant bits of the last byte. The 8 bit characters are "filled"
46 in order from most significant bit to least significant.
48 static void write_bits(sox_format_t
* ft
, INT32
*bits
, int len
)
51 uint8_t mask
; /* The next bit position within the variable "data" to
52 place the next bit. */
53 uint8_t data
; /* The contents of the next byte to place in the
56 /* Fill in the array bits.
57 * The first compressed output bit will be the most significant
58 * bit of the byte, so initialize mask to 0x80. The next byte of
59 * compressed data is initially 0, and the desired bits will be
65 for (i
= 0; i
< len
; i
++) {
66 /* Turn on the next bit of output data, if necessary. */
71 * If the byte data is full, determined by mask becoming 0,
72 * then write the byte to the output file, and reinitialize
73 * data and mask for the next output byte. Also add the byte
74 * if (i == len-1), because if len is not a multiple of 8,
75 * then mask won't yet be 0. */
77 if ((mask
== 0) || (i
== len
-1)) {
86 Read bits from file f into bits[0] through bits[len-1], in "packed"
89 Read ceiling(len/8) characters from file f, if that many are
90 available to read, otherwise read to the end of the file. The first
91 character's 8 bits, in order from MSB to LSB, are used to fill
92 bits[0] through bits[7]. The second character's bits are used to
93 fill bits[8] through bits[15], and so on. If ceiling(len/8)
94 characters are available to read, and len is not a multiple of 8,
95 then some of the least significant bits of the last character read
96 are completely ignored. Every entry of bits[] that is modified is
97 changed to either a 0 or a 1.
99 The number of bits successfully read is returned, and is always in
100 the range 0 to len, inclusive. If it is less than len, it will
101 always be a multiple of 8.
103 static int read_bits(sox_format_t
* ft
, INT32
*bits
, int len
)
108 /* Unpack the array bits into coded_frame. */
109 for (i
= 0; i
< len
; i
++) {
111 lsx_read_b_buf(ft
, &c
, (size_t) 1);
116 if (c
& (0x80 >> (i
& 7))) {
125 static int startread(sox_format_t
* ft
)
127 priv_t
* lpc
= (priv_t
*)ft
->priv
;
129 if ((lpc
->decst
= create_lpc10_decoder_state()) == NULL
) {
130 fprintf(stderr
, "lpc10 could not allocate decoder state");
133 lpc
->samples
= LPC10_SAMPLES_PER_FRAME
;
134 return lsx_check_read_params(ft
, 1, 8000., SOX_ENCODING_LPC10
, 0, (uint64_t)0, sox_false
);
137 static int startwrite(sox_format_t
* ft
)
139 priv_t
* lpc
= (priv_t
*)ft
->priv
;
141 if ((lpc
->encst
= create_lpc10_encoder_state()) == NULL
) {
142 fprintf(stderr
, "lpc10 could not allocate encoder state");
150 static size_t read_samples(sox_format_t
* ft
, sox_sample_t
*buf
, size_t len
)
152 priv_t
* lpc
= (priv_t
*)ft
->priv
;
155 while (nread
< len
) {
157 /* Read more data if buffer is empty */
158 if (lpc
->samples
== LPC10_SAMPLES_PER_FRAME
) {
159 INT32 bits
[LPC10_BITS_IN_COMPRESSED_FRAME
];
161 if (read_bits(ft
, bits
, LPC10_BITS_IN_COMPRESSED_FRAME
) !=
162 LPC10_BITS_IN_COMPRESSED_FRAME
)
164 lpc10_decode(bits
, lpc
->speech
, lpc
->decst
);
168 while (nread
< len
&& lpc
->samples
< LPC10_SAMPLES_PER_FRAME
)
169 buf
[nread
++] = SOX_FLOAT_32BIT_TO_SAMPLE(lpc
->speech
[lpc
->samples
++], ft
->clips
);
175 static size_t write_samples(sox_format_t
* ft
, const sox_sample_t
*buf
, size_t len
)
177 priv_t
* lpc
= (priv_t
*)ft
->priv
;
181 while (len
> 0 && lpc
->samples
< LPC10_SAMPLES_PER_FRAME
) {
183 lpc
->speech
[lpc
->samples
++] = SOX_SAMPLE_TO_FLOAT_32BIT(buf
[nwritten
++], ft
->clips
);
187 if (lpc
->samples
== LPC10_SAMPLES_PER_FRAME
) {
188 INT32 bits
[LPC10_BITS_IN_COMPRESSED_FRAME
];
190 lpc10_encode(lpc
->speech
, bits
, lpc
->encst
);
191 write_bits(ft
, bits
, LPC10_BITS_IN_COMPRESSED_FRAME
);
199 static int stopread(sox_format_t
* ft
)
201 priv_t
* lpc
= (priv_t
*)ft
->priv
;
208 static int stopwrite(sox_format_t
* ft
)
210 priv_t
* lpc
= (priv_t
*)ft
->priv
;
217 LSX_FORMAT_HANDLER(lpc10
)
219 static char const * const names
[] = {"lpc10", "lpc", NULL
};
220 static sox_rate_t
const write_rates
[] = {8000, 0};
221 static unsigned const write_encodings
[] = {SOX_ENCODING_LPC10
, 0, 0};
222 static sox_format_handler_t handler
= {SOX_LIB_VERSION_CODE
,
223 "Low bandwidth, robotic sounding speech compression", names
, SOX_FILE_MONO
,
224 startread
, read_samples
, stopread
,
225 startwrite
, write_samples
, stopwrite
,
226 NULL
, write_encodings
, write_rates
, sizeof(priv_t
)