Add float suffix to tansig_table literals.
[opus.git] / src / opus_multistream_decoder.c
1 /* Copyright (c) 2011 Xiph.Org Foundation
2    Written by Jean-Marc Valin */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14
15    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "opus_multistream.h"
33 #include "opus.h"
34 #include "opus_private.h"
35 #include "stack_alloc.h"
36 #include <stdarg.h>
37 #include "float_cast.h"
38 #include "os_support.h"
39
40 struct OpusMSDecoder {
41    ChannelLayout layout;
42    /* Decoder states go here */
43 };
44
45
46
47
48 /* DECODER */
49
50 opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
51 {
52    int coupled_size;
53    int mono_size;
54
55    if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
56    coupled_size = opus_decoder_get_size(2);
57    mono_size = opus_decoder_get_size(1);
58    return align(sizeof(OpusMSDecoder))
59          + nb_coupled_streams * align(coupled_size)
60          + (nb_streams-nb_coupled_streams) * align(mono_size);
61 }
62
63 int opus_multistream_decoder_init(
64       OpusMSDecoder *st,
65       opus_int32 Fs,
66       int channels,
67       int streams,
68       int coupled_streams,
69       const unsigned char *mapping
70 )
71 {
72    int coupled_size;
73    int mono_size;
74    int i, ret;
75    char *ptr;
76
77    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
78        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
79       return OPUS_BAD_ARG;
80
81    st->layout.nb_channels = channels;
82    st->layout.nb_streams = streams;
83    st->layout.nb_coupled_streams = coupled_streams;
84
85    for (i=0;i<st->layout.nb_channels;i++)
86       st->layout.mapping[i] = mapping[i];
87    if (!validate_layout(&st->layout))
88       return OPUS_BAD_ARG;
89
90    ptr = (char*)st + align(sizeof(OpusMSDecoder));
91    coupled_size = opus_decoder_get_size(2);
92    mono_size = opus_decoder_get_size(1);
93
94    for (i=0;i<st->layout.nb_coupled_streams;i++)
95    {
96       ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2);
97       if(ret!=OPUS_OK)return ret;
98       ptr += align(coupled_size);
99    }
100    for (;i<st->layout.nb_streams;i++)
101    {
102       ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1);
103       if(ret!=OPUS_OK)return ret;
104       ptr += align(mono_size);
105    }
106    return OPUS_OK;
107 }
108
109
110 OpusMSDecoder *opus_multistream_decoder_create(
111       opus_int32 Fs,
112       int channels,
113       int streams,
114       int coupled_streams,
115       const unsigned char *mapping,
116       int *error
117 )
118 {
119    int ret;
120    OpusMSDecoder *st;
121    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
122        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
123    {
124       if (error)
125          *error = OPUS_BAD_ARG;
126       return NULL;
127    }
128    st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
129    if (st==NULL)
130    {
131       if (error)
132          *error = OPUS_ALLOC_FAIL;
133       return NULL;
134    }
135    ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping);
136    if (error)
137       *error = ret;
138    if (ret != OPUS_OK)
139    {
140       opus_free(st);
141       st = NULL;
142    }
143    return st;
144 }
145
146 typedef void (*opus_copy_channel_out_func)(
147   void *dst,
148   int dst_stride,
149   int dst_channel,
150   const opus_val16 *src,
151   int src_stride,
152   int frame_size
153 );
154
155 static int opus_multistream_decode_native(
156       OpusMSDecoder *st,
157       const unsigned char *data,
158       opus_int32 len,
159       void *pcm,
160       opus_copy_channel_out_func copy_channel_out,
161       int frame_size,
162       int decode_fec
163 )
164 {
165    opus_int32 Fs;
166    int coupled_size;
167    int mono_size;
168    int s, c;
169    char *ptr;
170    int do_plc=0;
171    VARDECL(opus_val16, buf);
172    ALLOC_STACK;
173
174    /* Limit frame_size to avoid excessive stack allocations. */
175    opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));
176    frame_size = IMIN(frame_size, Fs/25*3);
177    ALLOC(buf, 2*frame_size, opus_val16);
178    ptr = (char*)st + align(sizeof(OpusMSDecoder));
179    coupled_size = opus_decoder_get_size(2);
180    mono_size = opus_decoder_get_size(1);
181
182    if (len==0)
183       do_plc = 1;
184    if (len < 0)
185       return OPUS_BAD_ARG;
186    if (!do_plc && len < 2*st->layout.nb_streams-1)
187       return OPUS_INVALID_PACKET;
188    for (s=0;s<st->layout.nb_streams;s++)
189    {
190       OpusDecoder *dec;
191       int packet_offset, ret;
192
193       dec = (OpusDecoder*)ptr;
194       ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
195
196       if (!do_plc && len<=0)
197       {
198          RESTORE_STACK;
199          return OPUS_INVALID_PACKET;
200       }
201       packet_offset = 0;
202       ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset);
203       data += packet_offset;
204       len -= packet_offset;
205       if (ret > frame_size)
206       {
207          RESTORE_STACK;
208          return OPUS_BUFFER_TOO_SMALL;
209       }
210       if (s>0 && ret != frame_size)
211       {
212          RESTORE_STACK;
213          return OPUS_INVALID_PACKET;
214       }
215       if (ret <= 0)
216       {
217          RESTORE_STACK;
218          return ret;
219       }
220       frame_size = ret;
221       if (s < st->layout.nb_coupled_streams)
222       {
223          int chan, prev;
224          prev = -1;
225          /* Copy "left" audio to the channel(s) where it belongs */
226          while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
227          {
228             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
229                buf, 2, frame_size);
230             prev = chan;
231          }
232          prev = -1;
233          /* Copy "right" audio to the channel(s) where it belongs */
234          while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
235          {
236             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
237                buf+1, 2, frame_size);
238             prev = chan;
239          }
240       } else {
241          int chan, prev;
242          prev = -1;
243          /* Copy audio to the channel(s) where it belongs */
244          while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
245          {
246             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
247                buf, 1, frame_size);
248             prev = chan;
249          }
250       }
251    }
252    /* Handle muted channels */
253    for (c=0;c<st->layout.nb_channels;c++)
254    {
255       if (st->layout.mapping[c] == 255)
256       {
257          (*copy_channel_out)(pcm, st->layout.nb_channels, c,
258             NULL, 0, frame_size);
259       }
260    }
261    RESTORE_STACK;
262    return frame_size;
263 }
264
265 #if !defined(DISABLE_FLOAT_API)
266 static void opus_copy_channel_out_float(
267   void *dst,
268   int dst_stride,
269   int dst_channel,
270   const opus_val16 *src,
271   int src_stride,
272   int frame_size
273 )
274 {
275    float *float_dst;
276    int i;
277    float_dst = (float*)dst;
278    if (src != NULL)
279    {
280       for (i=0;i<frame_size;i++)
281 #if defined(FIXED_POINT)
282          float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];
283 #else
284          float_dst[i*dst_stride+dst_channel] = src[i*src_stride];
285 #endif
286    }
287    else
288    {
289       for (i=0;i<frame_size;i++)
290          float_dst[i*dst_stride+dst_channel] = 0;
291    }
292 }
293 #endif
294
295 static void opus_copy_channel_out_short(
296   void *dst,
297   int dst_stride,
298   int dst_channel,
299   const opus_val16 *src,
300   int src_stride,
301   int frame_size
302 )
303 {
304    opus_int16 *short_dst;
305    int i;
306    short_dst = (opus_int16*)dst;
307    if (src != NULL)
308    {
309       for (i=0;i<frame_size;i++)
310 #if defined(FIXED_POINT)
311          short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
312 #else
313          short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
314 #endif
315    }
316    else
317    {
318       for (i=0;i<frame_size;i++)
319          short_dst[i*dst_stride+dst_channel] = 0;
320    }
321 }
322
323
324
325 #ifdef FIXED_POINT
326 int opus_multistream_decode(
327       OpusMSDecoder *st,
328       const unsigned char *data,
329       opus_int32 len,
330       opus_int16 *pcm,
331       int frame_size,
332       int decode_fec
333 )
334 {
335    return opus_multistream_decode_native(st, data, len,
336        pcm, opus_copy_channel_out_short, frame_size, decode_fec);
337 }
338
339 #ifndef DISABLE_FLOAT_API
340 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
341       opus_int32 len, float *pcm, int frame_size, int decode_fec)
342 {
343    return opus_multistream_decode_native(st, data, len,
344        pcm, opus_copy_channel_out_float, frame_size, decode_fec);
345 }
346 #endif
347
348 #else
349
350 int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
351       opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
352 {
353    return opus_multistream_decode_native(st, data, len,
354        pcm, opus_copy_channel_out_short, frame_size, decode_fec);
355 }
356
357 int opus_multistream_decode_float(
358       OpusMSDecoder *st,
359       const unsigned char *data,
360       opus_int32 len,
361       float *pcm,
362       int frame_size,
363       int decode_fec
364 )
365 {
366    return opus_multistream_decode_native(st, data, len,
367        pcm, opus_copy_channel_out_float, frame_size, decode_fec);
368 }
369 #endif
370
371 int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
372 {
373    va_list ap;
374    int coupled_size, mono_size;
375    char *ptr;
376    int ret = OPUS_OK;
377
378    va_start(ap, request);
379
380    coupled_size = opus_decoder_get_size(2);
381    mono_size = opus_decoder_get_size(1);
382    ptr = (char*)st + align(sizeof(OpusMSDecoder));
383    switch (request)
384    {
385        case OPUS_GET_BANDWIDTH_REQUEST:
386        case OPUS_GET_SAMPLE_RATE_REQUEST:
387        case OPUS_GET_GAIN_REQUEST:
388        case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
389        {
390           OpusDecoder *dec;
391           /* For int32* GET params, just query the first stream */
392           opus_int32 *value = va_arg(ap, opus_int32*);
393           dec = (OpusDecoder*)ptr;
394           ret = opus_decoder_ctl(dec, request, value);
395        }
396        break;
397        case OPUS_GET_FINAL_RANGE_REQUEST:
398        {
399           int s;
400           opus_uint32 *value = va_arg(ap, opus_uint32*);
401           opus_uint32 tmp;
402           *value = 0;
403           for (s=0;s<st->layout.nb_streams;s++)
404           {
405              OpusDecoder *dec;
406              dec = (OpusDecoder*)ptr;
407              if (s < st->layout.nb_coupled_streams)
408                 ptr += align(coupled_size);
409              else
410                 ptr += align(mono_size);
411              ret = opus_decoder_ctl(dec, request, &tmp);
412              if (ret != OPUS_OK) break;
413              *value ^= tmp;
414           }
415        }
416        break;
417        case OPUS_RESET_STATE:
418        {
419           int s;
420           for (s=0;s<st->layout.nb_streams;s++)
421           {
422              OpusDecoder *dec;
423
424              dec = (OpusDecoder*)ptr;
425              if (s < st->layout.nb_coupled_streams)
426                 ptr += align(coupled_size);
427              else
428                 ptr += align(mono_size);
429              ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
430              if (ret != OPUS_OK)
431                 break;
432           }
433        }
434        break;
435        case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
436        {
437           int s;
438           opus_int32 stream_id;
439           OpusDecoder **value;
440           stream_id = va_arg(ap, opus_int32);
441           if (stream_id<0 || stream_id >= st->layout.nb_streams)
442              ret = OPUS_BAD_ARG;
443           value = va_arg(ap, OpusDecoder**);
444           for (s=0;s<stream_id;s++)
445           {
446              if (s < st->layout.nb_coupled_streams)
447                 ptr += align(coupled_size);
448              else
449                 ptr += align(mono_size);
450           }
451           *value = (OpusDecoder*)ptr;
452        }
453        break;
454        case OPUS_SET_GAIN_REQUEST:
455        {
456           int s;
457           /* This works for int32 params */
458           opus_int32 value = va_arg(ap, opus_int32);
459           for (s=0;s<st->layout.nb_streams;s++)
460           {
461              OpusDecoder *dec;
462
463              dec = (OpusDecoder*)ptr;
464              if (s < st->layout.nb_coupled_streams)
465                 ptr += align(coupled_size);
466              else
467                 ptr += align(mono_size);
468              ret = opus_decoder_ctl(dec, request, value);
469              if (ret != OPUS_OK)
470                 break;
471           }
472        }
473        break;
474        default:
475           ret = OPUS_UNIMPLEMENTED;
476        break;
477    }
478
479    va_end(ap);
480    return ret;
481 }
482
483
484 void opus_multistream_decoder_destroy(OpusMSDecoder *st)
485 {
486     opus_free(st);
487 }