Applies soft-clipping to the int decoder API.
[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       int soft_clip
164 )
165 {
166    opus_int32 Fs;
167    int coupled_size;
168    int mono_size;
169    int s, c;
170    char *ptr;
171    int do_plc=0;
172    VARDECL(opus_val16, buf);
173    ALLOC_STACK;
174
175    /* Limit frame_size to avoid excessive stack allocations. */
176    opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));
177    frame_size = IMIN(frame_size, Fs/25*3);
178    ALLOC(buf, 2*frame_size, opus_val16);
179    ptr = (char*)st + align(sizeof(OpusMSDecoder));
180    coupled_size = opus_decoder_get_size(2);
181    mono_size = opus_decoder_get_size(1);
182
183    if (len==0)
184       do_plc = 1;
185    if (len < 0)
186       return OPUS_BAD_ARG;
187    if (!do_plc && len < 2*st->layout.nb_streams-1)
188       return OPUS_INVALID_PACKET;
189    for (s=0;s<st->layout.nb_streams;s++)
190    {
191       OpusDecoder *dec;
192       int packet_offset, ret;
193
194       dec = (OpusDecoder*)ptr;
195       ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
196
197       if (!do_plc && len<=0)
198       {
199          RESTORE_STACK;
200          return OPUS_INVALID_PACKET;
201       }
202       packet_offset = 0;
203       ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip);
204       data += packet_offset;
205       len -= packet_offset;
206       if (ret > frame_size)
207       {
208          RESTORE_STACK;
209          return OPUS_BUFFER_TOO_SMALL;
210       }
211       if (s>0 && ret != frame_size)
212       {
213          RESTORE_STACK;
214          return OPUS_INVALID_PACKET;
215       }
216       if (ret <= 0)
217       {
218          RESTORE_STACK;
219          return ret;
220       }
221       frame_size = ret;
222       if (s < st->layout.nb_coupled_streams)
223       {
224          int chan, prev;
225          prev = -1;
226          /* Copy "left" audio to the channel(s) where it belongs */
227          while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
228          {
229             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
230                buf, 2, frame_size);
231             prev = chan;
232          }
233          prev = -1;
234          /* Copy "right" audio to the channel(s) where it belongs */
235          while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
236          {
237             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
238                buf+1, 2, frame_size);
239             prev = chan;
240          }
241       } else {
242          int chan, prev;
243          prev = -1;
244          /* Copy audio to the channel(s) where it belongs */
245          while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
246          {
247             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
248                buf, 1, frame_size);
249             prev = chan;
250          }
251       }
252    }
253    /* Handle muted channels */
254    for (c=0;c<st->layout.nb_channels;c++)
255    {
256       if (st->layout.mapping[c] == 255)
257       {
258          (*copy_channel_out)(pcm, st->layout.nb_channels, c,
259             NULL, 0, frame_size);
260       }
261    }
262    RESTORE_STACK;
263    return frame_size;
264 }
265
266 #if !defined(DISABLE_FLOAT_API)
267 static void opus_copy_channel_out_float(
268   void *dst,
269   int dst_stride,
270   int dst_channel,
271   const opus_val16 *src,
272   int src_stride,
273   int frame_size
274 )
275 {
276    float *float_dst;
277    int i;
278    float_dst = (float*)dst;
279    if (src != NULL)
280    {
281       for (i=0;i<frame_size;i++)
282 #if defined(FIXED_POINT)
283          float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];
284 #else
285          float_dst[i*dst_stride+dst_channel] = src[i*src_stride];
286 #endif
287    }
288    else
289    {
290       for (i=0;i<frame_size;i++)
291          float_dst[i*dst_stride+dst_channel] = 0;
292    }
293 }
294 #endif
295
296 static void opus_copy_channel_out_short(
297   void *dst,
298   int dst_stride,
299   int dst_channel,
300   const opus_val16 *src,
301   int src_stride,
302   int frame_size
303 )
304 {
305    opus_int16 *short_dst;
306    int i;
307    short_dst = (opus_int16*)dst;
308    if (src != NULL)
309    {
310       for (i=0;i<frame_size;i++)
311 #if defined(FIXED_POINT)
312          short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
313 #else
314          short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
315 #endif
316    }
317    else
318    {
319       for (i=0;i<frame_size;i++)
320          short_dst[i*dst_stride+dst_channel] = 0;
321    }
322 }
323
324
325
326 #ifdef FIXED_POINT
327 int opus_multistream_decode(
328       OpusMSDecoder *st,
329       const unsigned char *data,
330       opus_int32 len,
331       opus_int16 *pcm,
332       int frame_size,
333       int decode_fec
334 )
335 {
336    return opus_multistream_decode_native(st, data, len,
337        pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0);
338 }
339
340 #ifndef DISABLE_FLOAT_API
341 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
342       opus_int32 len, float *pcm, int frame_size, int decode_fec)
343 {
344    return opus_multistream_decode_native(st, data, len,
345        pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
346 }
347 #endif
348
349 #else
350
351 int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
352       opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
353 {
354    return opus_multistream_decode_native(st, data, len,
355        pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1);
356 }
357
358 int opus_multistream_decode_float(
359       OpusMSDecoder *st,
360       const unsigned char *data,
361       opus_int32 len,
362       float *pcm,
363       int frame_size,
364       int decode_fec
365 )
366 {
367    return opus_multistream_decode_native(st, data, len,
368        pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
369 }
370 #endif
371
372 int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
373 {
374    va_list ap;
375    int coupled_size, mono_size;
376    char *ptr;
377    int ret = OPUS_OK;
378
379    va_start(ap, request);
380
381    coupled_size = opus_decoder_get_size(2);
382    mono_size = opus_decoder_get_size(1);
383    ptr = (char*)st + align(sizeof(OpusMSDecoder));
384    switch (request)
385    {
386        case OPUS_GET_BANDWIDTH_REQUEST:
387        case OPUS_GET_SAMPLE_RATE_REQUEST:
388        case OPUS_GET_GAIN_REQUEST:
389        case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
390        {
391           OpusDecoder *dec;
392           /* For int32* GET params, just query the first stream */
393           opus_int32 *value = va_arg(ap, opus_int32*);
394           dec = (OpusDecoder*)ptr;
395           ret = opus_decoder_ctl(dec, request, value);
396        }
397        break;
398        case OPUS_GET_FINAL_RANGE_REQUEST:
399        {
400           int s;
401           opus_uint32 *value = va_arg(ap, opus_uint32*);
402           opus_uint32 tmp;
403           *value = 0;
404           for (s=0;s<st->layout.nb_streams;s++)
405           {
406              OpusDecoder *dec;
407              dec = (OpusDecoder*)ptr;
408              if (s < st->layout.nb_coupled_streams)
409                 ptr += align(coupled_size);
410              else
411                 ptr += align(mono_size);
412              ret = opus_decoder_ctl(dec, request, &tmp);
413              if (ret != OPUS_OK) break;
414              *value ^= tmp;
415           }
416        }
417        break;
418        case OPUS_RESET_STATE:
419        {
420           int s;
421           for (s=0;s<st->layout.nb_streams;s++)
422           {
423              OpusDecoder *dec;
424
425              dec = (OpusDecoder*)ptr;
426              if (s < st->layout.nb_coupled_streams)
427                 ptr += align(coupled_size);
428              else
429                 ptr += align(mono_size);
430              ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
431              if (ret != OPUS_OK)
432                 break;
433           }
434        }
435        break;
436        case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
437        {
438           int s;
439           opus_int32 stream_id;
440           OpusDecoder **value;
441           stream_id = va_arg(ap, opus_int32);
442           if (stream_id<0 || stream_id >= st->layout.nb_streams)
443              ret = OPUS_BAD_ARG;
444           value = va_arg(ap, OpusDecoder**);
445           for (s=0;s<stream_id;s++)
446           {
447              if (s < st->layout.nb_coupled_streams)
448                 ptr += align(coupled_size);
449              else
450                 ptr += align(mono_size);
451           }
452           *value = (OpusDecoder*)ptr;
453        }
454        break;
455        case OPUS_SET_GAIN_REQUEST:
456        {
457           int s;
458           /* This works for int32 params */
459           opus_int32 value = va_arg(ap, opus_int32);
460           for (s=0;s<st->layout.nb_streams;s++)
461           {
462              OpusDecoder *dec;
463
464              dec = (OpusDecoder*)ptr;
465              if (s < st->layout.nb_coupled_streams)
466                 ptr += align(coupled_size);
467              else
468                 ptr += align(mono_size);
469              ret = opus_decoder_ctl(dec, request, value);
470              if (ret != OPUS_OK)
471                 break;
472           }
473        }
474        break;
475        default:
476           ret = OPUS_UNIMPLEMENTED;
477        break;
478    }
479
480    va_end(ap);
481    return ret;
482 }
483
484
485 void opus_multistream_decoder_destroy(OpusMSDecoder *st)
486 {
487     opus_free(st);
488 }