1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
//*****************************************************************************
//
// speexlib.c - interface to the speex coder/encoder library.
//
// Copyright (c) 2009-2014 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 2.1.0.12573 of the Tiva Utility Library.
//
//*****************************************************************************
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "third_party/speex-1.2rc1/include/speex/speex.h"
#include "third_party/speex-1.2rc1/include/speex/speex_header.h"
#include "utils/speexlib.h"
#include "driverlib/debug.h"
//*****************************************************************************
//
// The private structure that is used by the speex encoder or decoder for
// holding all state information for an encoder or decoder.
//
//*****************************************************************************
typedef struct
{
//
// Holds the state of the decoder.
//
void *pvState;
//
// Holds bits so they can be read and written to by the Speex routines
//
SpeexBits sBits;
//
// Holds the header information for the current file.
//
SpeexHeader sHeader;
//
// The current Segment table for the stream.
//
uint8_t pui8SegTable[256];
//
// The size of the current Segment table.
//
uint8_t ui8SegTableSize;
//
// The current active page in a segment.
//
uint8_t ui8PageCurrent;
//
// Current state flags.
//
uint32_t ui32Flags;
}
tSpeexInstance;
//*****************************************************************************
//
// The decoder and encoder instance data.
//
//*****************************************************************************
tSpeexInstance g_sSpeexDecoder, g_sSpeexEncoder;
//*****************************************************************************
//
//! Initialize the decoder's state to prepare for decoding new frames.
//!
//! This function will initializes the decoder so that it is prepared to start
//! receiving frames to decode.
//!
//! \return This function returns 0.
//
//*****************************************************************************
int32_t
SpeexDecodeInit(void)
{
int iTemp;
//
// Clear out the flags for this instance.
//
g_sSpeexDecoder.ui32Flags = 0;
//
// Create a new decoder state in narrow band mode.
//
g_sSpeexDecoder.pvState = speex_decoder_init(&speex_nb_mode);
//
// Disable enhanced decoding to reduce processing requirements.
//
iTemp = 0;
speex_decoder_ctl(g_sSpeexDecoder.pvState, SPEEX_SET_ENH, &iTemp);
//
// Initialization of the structure that holds the bits.
//
speex_bits_init(&g_sSpeexDecoder.sBits);
return(0);
}
//*****************************************************************************
//
//! This function returns the current frame size from the decoder.
//!
//! This function queries the decoder for the current decode frame size in byte
//! and returns it to the caller.
//!
//! \return The current decoder frame size.
//
//*****************************************************************************
int32_t
SpeexDecodeFrameSizeGet(void)
{
int iFrameSize;
//
// Return 0 if the wrong request is made.
//
iFrameSize = 0;
//
// Query the decoder for the current frame size.
//
speex_decoder_ctl(g_sSpeexDecoder.pvState, SPEEX_GET_FRAME_SIZE,
&iFrameSize);
return(iFrameSize);
}
//*****************************************************************************
//
//! This function decodes a single frame of Speex encoded audio.
//!
//! \param pui8InBuffer is the buffer that contains the Speex encoded audio.
//! \param ui32InSize is the number of valid bytes in the \e pui8InBuffer
//! buffer.
//! \param pui8OutBuffer is a pointer to the buffer to store decoded audio.
//! \param ui32OutSize is the size of the buffer pointed to by the
//! \e pui8OutBuffer pointer.
//!
//! This function will take a buffer of Speex encoded audio and decode it into
//! raw PCM audio. The \e pui16InBuffer parameter should contain a single
//! frame encoded Speex audio. The \e pui8OutBuffer will contain the decoded
//! audio after returning from this function.
//!
//! \return This function returns the number of decoded bytes in the
//! \e pui8OutBuffer buffer.
//
//*****************************************************************************
int32_t
SpeexDecode(uint8_t *pui8InBuffer, uint32_t ui32InSize, uint8_t *pui8OutBuffer,
uint32_t ui32OutSize)
{
int32_t i32Bytes;
//
// Read in the bit stream to the Speex library.
//
speex_bits_read_from(&g_sSpeexDecoder.sBits, (char *)pui8InBuffer,
ui32InSize);
//
// Decode one frame of data.
//
i32Bytes = speex_decode_int(g_sSpeexDecoder.pvState,
&g_sSpeexDecoder.sBits,
(int16_t *)pui8OutBuffer);
return(i32Bytes);
}
//*****************************************************************************
//
//! This function sets the current quality setting for the Speex encoder.
//!
//! \param iQuality is the new Quality setting to use for the Speex encoder.
//!
//! This function will use the \e iQuality setting as the new quality setting
//! for the Speex encoder.
//!
//! \return This function returns 0.
//
//*****************************************************************************
int32_t
SpeexEncodeQualitySet(int iQuality)
{
//
// Set the current encoder quality setting.
//
speex_encoder_ctl(g_sSpeexEncoder.pvState, SPEEX_SET_QUALITY, &iQuality);
return(0);
}
//*****************************************************************************
//
//! This function returns the current frame size from the encoder.
//!
//! This function queries the encoder for the current encode frame size in byte
//! and returns it to the caller.
//!
//! \return The current encoder frame size.
//
//*****************************************************************************
int32_t
SpeexEncodeFrameSizeGet(void)
{
int iFrameSize;
//
// Return 0 if the wrong request is made.
//
iFrameSize = 0;
//
// Query the encoder for the current frame size.
//
speex_encoder_ctl(g_sSpeexEncoder.pvState, SPEEX_GET_FRAME_SIZE,
&iFrameSize);
return(iFrameSize);
}
//*****************************************************************************
//
//! Initialize the encoder's state to prepare for encoding new frames.
//!
//! \param iSampleRate is the sample rate of the incoming audio.
//! \param iComplexity is the complexity setting for the encoder.
//! \param iQuality is the quality setting for the encoder.
//!
//! This function will initializes the encoder by setting the sample rate,
//! complexity and quality settings. The \e iComplexity and \e iQuality
//! settings are explained further in the Speex documentation.
//!
//! \return This function returns 0.
//
//*****************************************************************************
int32_t
SpeexEncodeInit(int iSampleRate, int iComplexity, int iQuality)
{
const SpeexMode *psMode;
//
// Clear out the flags for this instance.
//
g_sSpeexEncoder.ui32Flags = 0;
//
// Read out the current encoder mode.
//
psMode = speex_lib_get_mode(SPEEX_MODEID_NB);
//
// Create a new decoder state in narrow band mode.
//
g_sSpeexEncoder.pvState = speex_encoder_init(psMode);
//
// Initialize the bit stream.
//
speex_bits_init(&g_sSpeexEncoder.sBits);
//
// Set the quality.
//
SpeexEncodeQualitySet(iQuality);
//
// Set the complexity and sample rate for the encoder.
//
speex_encoder_ctl(g_sSpeexEncoder.pvState, SPEEX_SET_COMPLEXITY,
&iComplexity);
speex_encoder_ctl(g_sSpeexEncoder.pvState, SPEEX_SET_SAMPLING_RATE,
&iSampleRate);
return(0);
}
//*****************************************************************************
//
//! Encode a single frame of speex encoded audio.
//!
//! \param pui16InBuffer is the buffer that contains the raw PCM audio.
//! \param ui32InSize is the number of valid bytes in the \e pui16InBuffer
//! buffer.
//! \param pui8OutBuffer is a pointer to the buffer to store the encoded audio.
//! \param ui32OutSize is the size of the buffer pointed to by the
//! \e pui8OutBuffer pointer.
//!
//! This function will take a buffer of PCM audio and encode it into a frame
//! of speex compressed audio. The \e pui16InBuffer parameter should contain
//! a single frame of PCM audio. The \e pui8OutBuffer will contain the encoded
//! audio after returning from this function.
//!
//! \return This function returns the number of encoded bytes in the
//! \e pui8OutBuffer parameter.
//
//*****************************************************************************
int32_t
SpeexEncode(int16_t *pui16InBuffer, uint32_t ui32InSize,
uint8_t *pui8OutBuffer, uint32_t ui32OutSize)
{
int32_t i32Bytes;
//
// Reset the bit stream before encoding a new frame.
//
speex_bits_reset(&g_sSpeexEncoder.sBits);
//
// Encode a single frame.
//
speex_encode_int(g_sSpeexEncoder.pvState, pui16InBuffer,
&g_sSpeexEncoder.sBits);
//
// Read the PCM data from the encoded bit stream.
//
i32Bytes = speex_bits_write(&g_sSpeexEncoder.sBits, (char *)pui8OutBuffer,
ui32OutSize);
//
// Return the number of bytes in the PCM data.
//
return(i32Bytes);
}
//*****************************************************************************
//
// This is called by speex in the event of a fatal error.
//
//*****************************************************************************
void
_speex_fatal(const int8_t *str, const int8_t *file, int line)
{
ASSERT(0);
while(1)
{
}
}
//*****************************************************************************
//
// Speex wrapper for putc so that it does not use any file writing library
// functions. The speex library uses some file access for debug printing, this
// will disable this feature.
//
//*****************************************************************************
void
_speex_putc(int ch, void *file)
{
}
|