LCOV - code coverage report
Current view: top level - lib_rend - ivas_td_ring_buffer.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 0c62f5312a76f89f3e6d6ab9a8d50516c9ab4059 Lines: 83 87 95.4 %
Date: 2025-12-17 05:21:10 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <assert.h>
      34             : #include <stdint.h>
      35             : #include <stdlib.h>
      36             : #include "ivas_error_utils.h"
      37             : #include "ivas_prot_rend.h"
      38             : #include "options.h"
      39             : #include "wmc_auto.h"
      40             : 
      41             : 
      42             : /*-----------------------------------------------------------------------*
      43             :  * Local function prototypes
      44             :  *-----------------------------------------------------------------------*/
      45             : 
      46             : /*---------------------------------------------------------------------*
      47             :  * ivas_td_ringbuf_total_size()
      48             :  *
      49             :  * Returns total number of buffered samples (including number of channels)
      50             :  *---------------------------------------------------------------------*/
      51             : 
      52     6899761 : static int32_t ivas_td_ringbuf_total_size(
      53             :     TD_RINGBUF_HANDLE h )
      54             : {
      55     6899761 :     if ( h->is_full )
      56             :     {
      57       86531 :         return h->capacity;
      58             :     }
      59             : 
      60     6813230 :     if ( h->read_pos <= h->write_pos )
      61             :     {
      62     5091143 :         return h->write_pos - h->read_pos;
      63             :     }
      64             :     /* else wrap around */
      65     1722087 :     return h->write_pos + h->capacity - h->read_pos;
      66             : }
      67             : 
      68             : 
      69     3452918 : static int16_t ivas_td_ringbuf_has_space_for_num_samples(
      70             :     TD_RINGBUF_HANDLE h,
      71             :     const int32_t num_samples )
      72             : {
      73     3452918 :     return (int16_t) ( ivas_td_ringbuf_total_size( h ) + num_samples <= h->capacity );
      74             : }
      75             : 
      76             : 
      77       99210 : static void ivas_td_ringbuf_push_interleaved(
      78             :     TD_RINGBUF_HANDLE h,                   /* i/o: Ring buffer handle                                              */
      79             :     const float *data,                     /* i  : Input audio in interleaved channels layout                      */
      80             :     const int16_t num_samples_per_channel, /* i  : Number of samples per channel to push                           */
      81             :     const int16_t read_stride              /* i: : 1 for normal operation, 0 for reading from a single input value */
      82             : )
      83             : {
      84             :     int32_t s, read_s;
      85             : 
      86       99210 :     assert( h != NULL );
      87       99210 :     assert( data != NULL );
      88       99210 :     assert( read_stride == 0 || read_stride == 1 );
      89       99210 :     assert( ivas_td_ringbuf_has_space_for_num_samples( h, (int32_t) num_samples_per_channel * h->num_channels ) );
      90             : 
      91   568189336 :     for ( s = 0, read_s = 0; s < (int32_t) num_samples_per_channel * h->num_channels; ++s, read_s += read_stride )
      92             :     {
      93   568090126 :         h->data[h->write_pos] = data[read_s];
      94   568090126 :         ++h->write_pos;
      95             : 
      96   568090126 :         if ( h->write_pos == h->capacity )
      97             :         {
      98       86531 :             h->write_pos = 0;
      99             :         }
     100             :     }
     101             : 
     102       99210 :     if ( h->read_pos == h->write_pos )
     103             :     {
     104       86531 :         h->is_full = 1;
     105             :     }
     106             : 
     107       99210 :     return;
     108             : }
     109             : 
     110             : 
     111             : /*-----------------------------------------------------------------------*
     112             :  * Global function definitions
     113             :  *-----------------------------------------------------------------------*/
     114             : 
     115             : /*---------------------------------------------------------------------*
     116             :  * ivas_TD_RINGBUF_Open()
     117             :  *
     118             :  * Allocates a ring buffer for TD data with the given capacity of TD samples per channel.
     119             :  *
     120             :  * May return IVAS_ERR_FAILED_ALLOC on failed allocation, or IVAS_ERR_OK otherwise.
     121             :  *---------------------------------------------------------------------*/
     122             : 
     123        7068 : ivas_error ivas_TD_RINGBUF_Open(
     124             :     TD_RINGBUF_HANDLE *ph,              /* i/o: Ring buffer handle                     */
     125             :     const int16_t capacity_per_channel, /* i  : Number of samples stored per channel   */
     126             :     const int16_t num_channels          /* i  : Number of channels                     */
     127             : )
     128             : {
     129             :     TD_RINGBUF_HANDLE h;
     130             :     int32_t capacity;
     131             : 
     132        7068 :     capacity = (int32_t) capacity_per_channel * num_channels;
     133             : 
     134        7068 :     h = malloc( sizeof( TD_RINGBUF_DATA ) );
     135        7068 :     if ( h == NULL )
     136             :     {
     137           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for TD ring buffer\n" );
     138             :     }
     139        7068 :     h->data = NULL;
     140        7068 :     h->capacity = 0;
     141        7068 :     h->num_channels = num_channels;
     142        7068 :     h->write_pos = 0;
     143        7068 :     h->read_pos = 0;
     144        7068 :     h->is_full = 0;
     145        7068 :     *ph = h;
     146             : 
     147        7068 :     h->data = malloc( capacity * sizeof( float ) );
     148        7068 :     if ( h->data == NULL )
     149             :     {
     150           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for TD ring buffer\n" );
     151             :     }
     152        7068 :     h->capacity = capacity;
     153             : 
     154        7068 :     return IVAS_ERR_OK;
     155             : }
     156             : 
     157             : 
     158             : /*---------------------------------------------------------------------*
     159             :  * ivas_TD_RINGBUF_Close()
     160             :  *
     161             :  * Dellocates TD ring buffer. The given handle will be set to NULL.
     162             :  *---------------------------------------------------------------------*/
     163             : 
     164       72942 : void ivas_TD_RINGBUF_Close(
     165             :     TD_RINGBUF_HANDLE *ph /* i/o: Ring buffer handle */
     166             : )
     167             : {
     168             :     TD_RINGBUF_HANDLE h;
     169             : 
     170       72942 :     if ( ph == NULL )
     171             :     {
     172           0 :         return;
     173             :     }
     174       72942 :     h = *ph;
     175             : 
     176       72942 :     if ( h == NULL )
     177             :     {
     178       65874 :         return;
     179             :     }
     180             : 
     181        7068 :     if ( h->data != NULL )
     182             :     {
     183        7068 :         free( h->data );
     184             :     }
     185             : 
     186        7068 :     free( h );
     187        7068 :     *ph = NULL;
     188             : 
     189        7068 :     return;
     190             : }
     191             : 
     192             : 
     193             : /*---------------------------------------------------------------------*
     194             :  * ivas_TD_RINGBUF_PushInterleaved()
     195             :  *
     196             :  * Pushes samples from a buffer with interleaved channel layout onto the back of the TD ring buffer.
     197             :  *---------------------------------------------------------------------*/
     198             : 
     199       92606 : void ivas_TD_RINGBUF_PushInterleaved(
     200             :     TD_RINGBUF_HANDLE h,                  /* i/o: Ring buffer handle                           */
     201             :     const float *data,                    /* i  : Input audio in interleaved channels layout   */
     202             :     const int16_t num_samples_per_channel /* i  : Number of samples per channel to push        */
     203             : )
     204             : {
     205       92606 :     ivas_td_ringbuf_push_interleaved( h, data, num_samples_per_channel, 1 );
     206             : 
     207       92606 :     return;
     208             : }
     209             : 
     210             : 
     211             : /*---------------------------------------------------------------------*
     212             :  * ivas_TD_RINGBUF_PushChannels()
     213             :  *
     214             :  * Pushes samples from channel pointers onto the back of the TD ring buffer.
     215             :  *---------------------------------------------------------------------*/
     216             : 
     217     3353708 : void ivas_TD_RINGBUF_PushChannels(
     218             :     TD_RINGBUF_HANDLE h,                  /* i/o: Ring buffer handle                       */
     219             :     const float *p_channels[],            /* i  : Array of pointers to each input channel  */
     220             :     const int16_t num_samples_per_channel /* i  : Number of samples per channel to push    */
     221             : )
     222             : {
     223             :     int32_t s;
     224             :     int16_t c;
     225             : 
     226     3353708 :     assert( h != NULL );
     227     3353708 :     assert( p_channels != NULL );
     228    19471568 :     for ( c = 0; c < h->num_channels; ++c )
     229             :     {
     230    16117860 :         assert( p_channels[c] != NULL );
     231             :     }
     232     3353708 :     assert( ivas_td_ringbuf_has_space_for_num_samples( h, (int32_t) num_samples_per_channel * h->num_channels ) );
     233             : 
     234  1041326508 :     for ( s = 0; s < num_samples_per_channel; ++s )
     235             :     {
     236  6485550400 :         for ( c = 0; c < h->num_channels; ++c )
     237             :         {
     238  5447577600 :             h->data[h->write_pos] = p_channels[c][s];
     239  5447577600 :             ++h->write_pos;
     240             : 
     241  5447577600 :             if ( h->write_pos == h->capacity )
     242             :             {
     243     1437155 :                 h->write_pos = 0;
     244             :             }
     245             :         }
     246             :     }
     247             : 
     248     3353708 :     if ( h->read_pos == h->write_pos )
     249             :     {
     250           0 :         h->is_full = 1;
     251             :     }
     252             : 
     253     3353708 :     return;
     254             : }
     255             : 
     256             : 
     257             : /*---------------------------------------------------------------------*
     258             :  * ivas_TD_RINGBUF_PushConstant()
     259             :  *
     260             :  * Pushes samples with a constant value onto the back of the TD ring buffer.
     261             :  *---------------------------------------------------------------------*/
     262             : 
     263        6604 : void ivas_TD_RINGBUF_PushConstant(
     264             :     TD_RINGBUF_HANDLE h,                  /* i/o: Ring buffer handle                      */
     265             :     const float value,                    /* i  : Value to push                           */
     266             :     const int16_t num_samples_per_channel /* i  : Number of samples per channel to push   */
     267             : )
     268             : {
     269        6604 :     ivas_td_ringbuf_push_interleaved( h, &value, num_samples_per_channel, 0 );
     270             : 
     271        6604 :     return;
     272             : }
     273             : 
     274             : 
     275             : /*---------------------------------------------------------------------*
     276             :  * ivas_TD_RINGBUF_PopChannels()
     277             :  *
     278             :  * Pops samples from the front of the TD ring buffer to an array of channel pointers.
     279             :  *---------------------------------------------------------------------*/
     280             : 
     281     3440239 : void ivas_TD_RINGBUF_PopChannels(
     282             :     TD_RINGBUF_HANDLE h,                  /* i/o: Ring buffer handle                       */
     283             :     float *p_channels[],                  /* i  : Array of pointers to each output channel */
     284             :     const int16_t num_samples_per_channel /* i  : Number of samples per channel to pop     */
     285             : )
     286             : {
     287             :     int32_t s;
     288             :     int16_t c;
     289             : 
     290     3440239 :     assert( h != NULL );
     291     3440239 :     assert( p_channels != NULL );
     292    20164009 :     for ( c = 0; c < h->num_channels; ++c )
     293             :     {
     294    16723770 :         assert( p_channels[c] != NULL );
     295             :     }
     296     3440239 :     assert( ivas_td_ringbuf_total_size( h ) >= (int32_t) num_samples_per_channel * h->num_channels );
     297             : 
     298  1118087943 :     for ( s = 0; s < num_samples_per_channel; ++s )
     299             :     {
     300  7130315430 :         for ( c = 0; c < h->num_channels; ++c )
     301             :         {
     302  6015667726 :             p_channels[c][s] = h->data[h->read_pos];
     303  6015667726 :             ++h->read_pos;
     304             : 
     305  6015667726 :             if ( h->read_pos == h->capacity )
     306             :             {
     307     1523686 :                 h->read_pos = 0;
     308             :             }
     309             :         }
     310             :     }
     311             : 
     312     3440239 :     if ( num_samples_per_channel != 0 )
     313             :     {
     314     3440239 :         h->is_full = 0;
     315             :     }
     316             : 
     317     3440239 :     return;
     318             : }
     319             : 
     320             : 
     321             : /*---------------------------------------------------------------------*
     322             :  * ivas_TD_RINGBUF_Size()
     323             :  *
     324             :  * Returns number of buffered samples per channel.
     325             :  *---------------------------------------------------------------------*/
     326             : 
     327        6604 : int16_t ivas_TD_RINGBUF_Size(
     328             :     const TD_RINGBUF_HANDLE h /* i  : Ring buffer handle */
     329             : )
     330             : {
     331        6604 :     return (int16_t) ( ivas_td_ringbuf_total_size( h ) / h->num_channels );
     332             : }

Generated by: LCOV version 1.14