diff options
Diffstat (limited to 'apps/codecs')
-rw-r--r-- | apps/codecs/aiff.c | 6 | ||||
-rw-r--r-- | apps/codecs/libpcm/SOURCES | 1 | ||||
-rw-r--r-- | apps/codecs/libpcm/ieee_float.c | 147 | ||||
-rw-r--r-- | apps/codecs/libpcm/support_formats.h | 3 | ||||
-rw-r--r-- | apps/codecs/wav.c | 4 |
5 files changed, 159 insertions, 2 deletions
diff --git a/apps/codecs/aiff.c b/apps/codecs/aiff.c index 497e0c7c3a..2e10d1e416 100644 --- a/apps/codecs/aiff.c +++ b/apps/codecs/aiff.c | |||
@@ -34,15 +34,19 @@ enum { | |||
34 | AIFC_FORMAT_PCM = FOURCC('N', 'O', 'N', 'E'), /* AIFC PCM Format (big endian) */ | 34 | AIFC_FORMAT_PCM = FOURCC('N', 'O', 'N', 'E'), /* AIFC PCM Format (big endian) */ |
35 | AIFC_FORMAT_ALAW = FOURCC('a', 'l', 'a', 'w'), /* AIFC ALaw compressed */ | 35 | AIFC_FORMAT_ALAW = FOURCC('a', 'l', 'a', 'w'), /* AIFC ALaw compressed */ |
36 | AIFC_FORMAT_MULAW = FOURCC('u', 'l', 'a', 'w'), /* AIFC uLaw compressed */ | 36 | AIFC_FORMAT_MULAW = FOURCC('u', 'l', 'a', 'w'), /* AIFC uLaw compressed */ |
37 | AIFC_FORMAT_IEEE_FLOAT32 = FOURCC('f', 'l', '3', '2'), /* AIFC IEEE float 32 bit */ | ||
38 | AIFC_FORMAT_IEEE_FLOAT64 = FOURCC('f', 'l', '6', '4'), /* AIFC IEEE float 64 bit */ | ||
37 | }; | 39 | }; |
38 | 40 | ||
39 | static const struct pcm_entry pcm_codecs[] = { | 41 | static const struct pcm_entry pcm_codecs[] = { |
40 | { AIFC_FORMAT_PCM, get_linear_pcm_codec }, | 42 | { AIFC_FORMAT_PCM, get_linear_pcm_codec }, |
41 | { AIFC_FORMAT_ALAW, get_itut_g711_alaw_codec }, | 43 | { AIFC_FORMAT_ALAW, get_itut_g711_alaw_codec }, |
42 | { AIFC_FORMAT_MULAW, get_itut_g711_mulaw_codec }, | 44 | { AIFC_FORMAT_MULAW, get_itut_g711_mulaw_codec }, |
45 | { AIFC_FORMAT_IEEE_FLOAT32, get_ieee_float_codec }, | ||
46 | { AIFC_FORMAT_IEEE_FLOAT64, get_ieee_float_codec }, | ||
43 | }; | 47 | }; |
44 | 48 | ||
45 | #define NUM_FORMATS 3 | 49 | #define NUM_FORMATS 5 |
46 | 50 | ||
47 | static int32_t samples[PCM_CHUNK_SIZE] IBSS_ATTR; | 51 | static int32_t samples[PCM_CHUNK_SIZE] IBSS_ATTR; |
48 | 52 | ||
diff --git a/apps/codecs/libpcm/SOURCES b/apps/codecs/libpcm/SOURCES index e921584f7c..89be3452b1 100644 --- a/apps/codecs/libpcm/SOURCES +++ b/apps/codecs/libpcm/SOURCES | |||
@@ -1,3 +1,4 @@ | |||
1 | linear_pcm.c | 1 | linear_pcm.c |
2 | itut_g711.c | 2 | itut_g711.c |
3 | dvi_adpcm.c | 3 | dvi_adpcm.c |
4 | ieee_float.c | ||
diff --git a/apps/codecs/libpcm/ieee_float.c b/apps/codecs/libpcm/ieee_float.c new file mode 100644 index 0000000000..a5c50e845e --- /dev/null +++ b/apps/codecs/libpcm/ieee_float.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2009 Yoshihisa Uchida | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "codeclib.h" | ||
22 | #include "pcm_common.h" | ||
23 | |||
24 | /* | ||
25 | * IEEE float | ||
26 | */ | ||
27 | |||
28 | static struct pcm_format *fmt; | ||
29 | |||
30 | static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) | ||
31 | { | ||
32 | fmt = format; | ||
33 | |||
34 | (void)fmtpos; | ||
35 | |||
36 | if (fmt->bitspersample != 32 && fmt->bitspersample != 64) | ||
37 | { | ||
38 | DEBUGF("CODEC_ERROR: ieee float must be 32 or 64 bitspersample %d\n", fmt->bitspersample); | ||
39 | return false; | ||
40 | } | ||
41 | |||
42 | fmt->bytespersample = fmt->bitspersample >> 3; | ||
43 | fmt->blockalign = fmt->bytespersample; | ||
44 | |||
45 | /* chunksize is computed so that one chunk is about 1/50s. */ | ||
46 | fmt->chunksize = (ci->id3->frequency * fmt->channels / 50) * fmt->blockalign; | ||
47 | |||
48 | return true; | ||
49 | } | ||
50 | |||
51 | static uint32_t get_seek_pos(long seek_time) | ||
52 | { | ||
53 | uint32_t newpos; | ||
54 | |||
55 | newpos = ((uint64_t)(seek_time * ci->id3->frequency * fmt->channels / 1000LL))*fmt->blockalign; | ||
56 | return newpos; | ||
57 | } | ||
58 | |||
59 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
60 | int32_t *outbuf, int *outbufsize) | ||
61 | { | ||
62 | uint32_t i; | ||
63 | int32_t pcm; | ||
64 | int16_t exp; | ||
65 | int sgn; | ||
66 | |||
67 | if (fmt->bitspersample == 32) | ||
68 | { | ||
69 | for (i = 0; i < inbufsize; i += 4) | ||
70 | { | ||
71 | if (fmt->is_little_endian) | ||
72 | { | ||
73 | pcm = (inbuf[0]<<5)|(inbuf[1]<<13)|((inbuf[2]|0x80)<<21); | ||
74 | exp = ((inbuf[2]>>7)|((inbuf[3]&0x7f)<<1)) - 127; | ||
75 | sgn = inbuf[3] & 0x80; | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | pcm = (inbuf[3]<<5)|(inbuf[2]<<13)|((inbuf[1]|0x80)<<21); | ||
80 | exp = ((inbuf[1]>>7)|((inbuf[0]&0x7f)<<1)) - 127; | ||
81 | sgn = inbuf[0] & 0x80; | ||
82 | } | ||
83 | if (exp > -29 && exp < 0) | ||
84 | { | ||
85 | pcm >>= -exp; | ||
86 | if (sgn) | ||
87 | pcm = -pcm; | ||
88 | } | ||
89 | else if (exp < -28) | ||
90 | pcm = 0; | ||
91 | else | ||
92 | pcm = (sgn)?-(1<<28):(1<<28)-1; | ||
93 | |||
94 | outbuf[i/4] = pcm; | ||
95 | inbuf += 4; | ||
96 | } | ||
97 | *outbufsize = inbufsize >> 2; | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | for (i = 0; i < inbufsize; i += 8) | ||
102 | { | ||
103 | if (fmt->is_little_endian) | ||
104 | { | ||
105 | pcm = inbuf[3]|(inbuf[4]<<8)|(inbuf[5]<<16)|(((inbuf[6]&0x0f)|0x10)<<24); | ||
106 | exp = (((inbuf[6]&0xf0)>>4)|((inbuf[7]&0x7f)<<4)) - 1023; | ||
107 | sgn = inbuf[7] & 0x80; | ||
108 | } | ||
109 | else | ||
110 | { | ||
111 | pcm = inbuf[4]|(inbuf[3]<<8)|(inbuf[2]<<16)|(((inbuf[1]&0x0f)|0x10)<<24); | ||
112 | exp = (((inbuf[1]&0xf0)>>4)|((inbuf[0]&0x7f)<<4)) - 1023; | ||
113 | sgn = inbuf[0] & 0x80; | ||
114 | } | ||
115 | if (exp > -29 && exp < 0) | ||
116 | { | ||
117 | pcm >>= -exp; | ||
118 | if (sgn) | ||
119 | pcm = -pcm; | ||
120 | } | ||
121 | else if (exp < -28) | ||
122 | pcm = 0; | ||
123 | else | ||
124 | pcm = (sgn)?-(1<<28):(1<<28)-1; | ||
125 | |||
126 | outbuf[i/8] = pcm; | ||
127 | inbuf += 8; | ||
128 | } | ||
129 | *outbufsize = inbufsize >> 3; | ||
130 | } | ||
131 | |||
132 | if (fmt->channels == 2) | ||
133 | *outbufsize >>= 1; | ||
134 | |||
135 | return CODEC_OK; | ||
136 | } | ||
137 | |||
138 | static const struct pcm_codec codec = { | ||
139 | set_format, | ||
140 | get_seek_pos, | ||
141 | decode, | ||
142 | }; | ||
143 | |||
144 | const struct pcm_codec *get_ieee_float_codec(void) | ||
145 | { | ||
146 | return &codec; | ||
147 | } | ||
diff --git a/apps/codecs/libpcm/support_formats.h b/apps/codecs/libpcm/support_formats.h index 9a1f4f764d..0a6ea339f4 100644 --- a/apps/codecs/libpcm/support_formats.h +++ b/apps/codecs/libpcm/support_formats.h | |||
@@ -34,4 +34,7 @@ const struct pcm_codec *get_itut_g711_mulaw_codec(void); | |||
34 | 34 | ||
35 | /* Intel DVI ADPCM */ | 35 | /* Intel DVI ADPCM */ |
36 | const struct pcm_codec *get_dvi_adpcm_codec(void); | 36 | const struct pcm_codec *get_dvi_adpcm_codec(void); |
37 | |||
38 | /* IEEE float */ | ||
39 | const struct pcm_codec *get_ieee_float_codec(void); | ||
37 | #endif | 40 | #endif |
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c index 774cfaf8ef..25a82cbcfe 100644 --- a/apps/codecs/wav.c +++ b/apps/codecs/wav.c | |||
@@ -45,6 +45,7 @@ enum | |||
45 | { | 45 | { |
46 | WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */ | 46 | WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */ |
47 | WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */ | 47 | WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */ |
48 | WAVE_FORMAT_IEEE_FLOAT = 0x0003, /* IEEE Float */ | ||
48 | WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */ | 49 | WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */ |
49 | WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */ | 50 | WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */ |
50 | WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */ | 51 | WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */ |
@@ -56,6 +57,7 @@ enum | |||
56 | const struct pcm_entry wave_codecs[] = { | 57 | const struct pcm_entry wave_codecs[] = { |
57 | { WAVE_FORMAT_UNKNOWN, 0 }, | 58 | { WAVE_FORMAT_UNKNOWN, 0 }, |
58 | { WAVE_FORMAT_PCM, get_linear_pcm_codec }, | 59 | { WAVE_FORMAT_PCM, get_linear_pcm_codec }, |
60 | { WAVE_FORMAT_IEEE_FLOAT, get_ieee_float_codec }, | ||
59 | { WAVE_FORMAT_ALAW, get_itut_g711_alaw_codec }, | 61 | { WAVE_FORMAT_ALAW, get_itut_g711_alaw_codec }, |
60 | { WAVE_FORMAT_MULAW, get_itut_g711_mulaw_codec }, | 62 | { WAVE_FORMAT_MULAW, get_itut_g711_mulaw_codec }, |
61 | { WAVE_FORMAT_DVI_ADPCM, get_dvi_adpcm_codec }, | 63 | { WAVE_FORMAT_DVI_ADPCM, get_dvi_adpcm_codec }, |
@@ -63,7 +65,7 @@ const struct pcm_entry wave_codecs[] = { | |||
63 | { IBM_FORMAT_ALAW, get_itut_g711_alaw_codec }, | 65 | { IBM_FORMAT_ALAW, get_itut_g711_alaw_codec }, |
64 | }; | 66 | }; |
65 | 67 | ||
66 | #define NUM_FORMATS 7 | 68 | #define NUM_FORMATS 8 |
67 | 69 | ||
68 | static const struct pcm_codec *get_wave_codec(uint32_t formattag) | 70 | static const struct pcm_codec *get_wave_codec(uint32_t formattag) |
69 | { | 71 | { |