Initial port of RIFF-WAVE (.wav) sound datatype (v50.3) by Fredrik Wikstrom <fredrik...
[AROS.git] / workbench / classes / datatypes / wav / wave_gsm610.c
blob703698d62b3e632d1f1f3ed1a356faa483658cc8
1 /*
2 * wave.datatype
3 * (c) Fredrik Wikstrom
4 */
6 #include "wave_gsm610.h"
7 #include "gsm/private.h"
9 struct GSM610_Format {
10 UWORD formatTag;
11 WORD numChannels;
12 LONG samplesPerSec;
13 LONG avgBytesPerSec;
14 WORD blockAlign; /* amount to read for each block */
15 WORD bitsPerSample;
17 WORD extraSize; /* 2 */
18 WORD samplesPerBlock;
21 struct gsmstate {
22 gsm handle;
23 gsm_signal *samples;
26 DEC_SETUPPROTO(SetupGSM610) {
27 //int valP = 1;
28 struct ClassBase * libBase;
29 struct GSM610_Format * fmt;
30 struct gsmstate * state;
32 libBase = data->libBase;
33 fmt = (struct GSM610_Format *)data->fmt;
35 if (fmt->numChannels != 1)
36 return ERROR_NOT_IMPLEMENTED;
38 data->state = state = AllocVec(sizeof(*state), MEMF_CLEAR);
39 if (!state) return ERROR_NO_FREE_STORE;
41 // state->handle = gsm_create();
42 state->handle = (gsm)AllocMem(sizeof(struct gsm_state), MEMF_CLEAR);
43 if (!state->handle)
44 return ERROR_NO_FREE_STORE;
45 state->handle->nrp=40;
47 // gsm_option(state->handle, GSM_OPT_WAV49, &valP);
48 state->handle->wav_fmt = TRUE;
50 fmt->blockAlign = 65;
51 if (fmt->extraSize == 0 || fmt->samplesPerBlock == 0)
52 data->blockFrames = 320;
53 else if (fmt->extraSize == 2)
54 data->blockFrames = read_le16(&fmt->samplesPerBlock);
55 else
56 return NOTOK;
58 state->samples = AllocVec(2*data->blockFrames, MEMF_CLEAR);
59 if (!state->samples)
60 return ERROR_NO_FREE_STORE;
62 return OK;
65 DEC_CLEANUPPROTO(CleanupGSM610) {
66 struct ClassBase * libBase;
67 struct gsmstate * state;
69 libBase = data->libBase;
70 state = (struct gsmstate *)data->state;
72 FreeVec(state->samples);
74 // gsm_destroy(state->handle);
75 if (state->handle) FreeMem(state->handle, sizeof(struct gsm_state));
77 FreeVec(state);
80 DECODERPROTO(DecodeGSM610) {
81 struct gsmstate * state;
82 gsm_signal *buff;
83 LONG ch, fr;
84 state = (struct gsmstate *)data->state;
86 for (ch = 0; ch < fmt->numChannels; ch++) {
87 /* decode the long 33 byte half */
88 if (gsm_decode(state->handle, Src, state->samples) < 0) {
89 return 0;
91 /* decode the short 32 byte half */
92 if (gsm_decode(state->handle, Src+33, state->samples+160) < 0) {
93 return 0;
95 buff = state->samples;
96 for (fr = 0; fr < numFrames; fr++) {
97 *Dst[ch]++ = (*buff++)>> 8;
101 return numFrames;