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 @ fec202a8f89be4a2f278a9fc377bfb58b58fab11 Lines: 64 73 87.7 %
Date: 2025-09-12 08:48:38 Functions: 8 8 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 <stdlib.h>
      35             : #include "ivas_error_utils.h"
      36             : #include "ivas_prot_rend.h"
      37             : #include "options.h"
      38             : #include "wmc_auto.h"
      39             : 
      40             : 
      41             : /*-----------------------------------------------------------------------*
      42             :  * Local function prototypes
      43             :  *-----------------------------------------------------------------------*/
      44             : 
      45    10198800 : static uint32_t ivas_td_ringbuf_total_size(
      46             :     TD_RINGBUF_HANDLE h )
      47             : {
      48    10198800 :     if ( h->is_full )
      49             :     {
      50           0 :         return h->capacity;
      51             :     }
      52             : 
      53    10198800 :     if ( h->read_pos <= h->write_pos )
      54             :     {
      55     7594776 :         return h->write_pos - h->read_pos;
      56             :     }
      57             :     /* else wrap around */
      58     2604024 :     return h->write_pos + h->capacity - h->read_pos;
      59             : }
      60             : 
      61             : 
      62     5099400 : static int16_t ivas_td_ringbuf_has_space_for_num_samples(
      63             :     TD_RINGBUF_HANDLE h,
      64             :     const uint32_t num_samples )
      65             : {
      66     5099400 :     return (int16_t) ( ivas_td_ringbuf_total_size( h ) + num_samples <= h->capacity );
      67             : }
      68             : 
      69             : 
      70             : /*-----------------------------------------------------------------------*
      71             :  * Global function definitions
      72             :  *-----------------------------------------------------------------------*/
      73             : 
      74             : /*---------------------------------------------------------------------*
      75             :  * ivas_TD_RINGBUF_Open()
      76             :  *
      77             :  * Allocate a ring buffer for TD data with the given capacity of TD samples per channel.
      78             :  *
      79             :  * May return IVAS_ERR_FAILED_ALLOC on failed allocation, or IVAS_ERR_OK otherwise.
      80             :  *---------------------------------------------------------------------*/
      81             : 
      82        5584 : ivas_error ivas_TD_RINGBUF_Open(
      83             :     TD_RINGBUF_HANDLE *ph,               /* i/o: Ring buffer handle                     */
      84             :     const uint32_t capacity_per_channel, /* i  : Number of samples stored per channel   */
      85             :     const uint16_t num_channels          /* i  : Number of channels                     */
      86             : )
      87             : {
      88             :     TD_RINGBUF_HANDLE h;
      89             :     uint32_t capacity;
      90             : 
      91        5584 :     capacity = capacity_per_channel * num_channels;
      92             : 
      93        5584 :     h = malloc( sizeof( TD_RINGBUF_DATA ) );
      94        5584 :     if ( h == NULL )
      95             :     {
      96           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for TD ring buffer\n" );
      97             :     }
      98        5584 :     h->data = NULL;
      99        5584 :     h->capacity = 0;
     100        5584 :     h->num_channels = num_channels;
     101        5584 :     h->write_pos = 0;
     102        5584 :     h->read_pos = 0;
     103        5584 :     h->is_full = 0;
     104        5584 :     *ph = h;
     105             : 
     106        5584 :     h->data = malloc( capacity * sizeof( float ) );
     107        5584 :     if ( h->data == NULL )
     108             :     {
     109           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for TD ring buffer\n" );
     110             :     }
     111        5584 :     h->capacity = capacity;
     112             : 
     113        5584 :     return IVAS_ERR_OK;
     114             : }
     115             : 
     116             : 
     117             : /*---------------------------------------------------------------------*
     118             :  * ivas_TD_RINGBUF_Close()
     119             :  *
     120             :  * Dellocate TD ring buffer. The given handle will be set to NULL.
     121             : 
     122             :  *---------------------------------------------------------------------*/
     123             : 
     124       58674 : void ivas_TD_RINGBUF_Close(
     125             :     TD_RINGBUF_HANDLE *ph /* i/o: Ring buffer handle */
     126             : )
     127             : {
     128             :     TD_RINGBUF_HANDLE h;
     129             : 
     130       58674 :     if ( ph == NULL )
     131             :     {
     132           0 :         return;
     133             :     }
     134       58674 :     h = *ph;
     135             : 
     136       58674 :     if ( h == NULL )
     137             :     {
     138       53090 :         return;
     139             :     }
     140             : 
     141        5584 :     if ( h->data != NULL )
     142             :     {
     143        5584 :         free( h->data );
     144             :     }
     145             : 
     146        5584 :     free( h );
     147        5584 :     *ph = NULL;
     148             : 
     149        5584 :     return;
     150             : }
     151             : 
     152             : 
     153             : /*---------------------------------------------------------------------*
     154             :  * ivas_TD_RINGBUF_Push()
     155             :  *
     156             :  * Push samples onto the back of the TD ring buffer.
     157             :  * Returns total number of buffered samples (includes number of channels)
     158             :  *---------------------------------------------------------------------*/
     159             : 
     160     5093816 : void ivas_TD_RINGBUF_Push(
     161             :     TD_RINGBUF_HANDLE h,                   /* i/o: Ring buffer handle                       */
     162             :     const float *data,                     /* i  : Input data                               */
     163             :     const uint32_t num_samples_per_channel /* i  : Number of samples per channel to store   */
     164             : )
     165             : {
     166             :     uint32_t s;
     167             :     uint16_t c;
     168             : 
     169     5093816 :     assert( ivas_td_ringbuf_has_space_for_num_samples( h, num_samples_per_channel * h->num_channels ) );
     170             : 
     171  1595001016 :     for ( s = 0; s < num_samples_per_channel; ++s )
     172             :     {
     173 11196684800 :         for ( c = 0; c < h->num_channels; ++c )
     174             :         {
     175  9606777600 :             h->data[h->write_pos] = *( data + c * num_samples_per_channel + s );
     176  9606777600 :             ++h->write_pos;
     177             : 
     178  9606777600 :             if ( h->write_pos == h->capacity )
     179             :             {
     180     2233288 :                 h->write_pos = 0;
     181             :             }
     182             :         }
     183             :     }
     184             : 
     185     5093816 :     if ( h->read_pos == h->write_pos )
     186             :     {
     187           0 :         h->is_full = 1;
     188             :     }
     189             : 
     190     5093816 :     return;
     191             : }
     192             : 
     193             : 
     194             : /*---------------------------------------------------------------------*
     195             :  * ivas_TD_RINGBUF_PushZeros()
     196             :  *
     197             :  * Push zero samples onto the back of the TD ring buffer.
     198             :  *---------------------------------------------------------------------*/
     199             : 
     200        5584 : void ivas_TD_RINGBUF_PushZeros(
     201             :     TD_RINGBUF_HANDLE h,                   /* i/o: Ring buffer handle                   */
     202             :     const uint32_t num_samples_per_channel /* i  : Number of zeros per channel to store */
     203             : )
     204             : {
     205             :     uint32_t s;
     206             :     uint16_t c;
     207             : 
     208        5584 :     assert( ivas_td_ringbuf_has_space_for_num_samples( h, num_samples_per_channel * h->num_channels ) );
     209        5584 :     if ( !num_samples_per_channel )
     210             :     {
     211           0 :         return;
     212             :     }
     213             : 
     214      655248 :     for ( s = 0; s < num_samples_per_channel; ++s )
     215             :     {
     216     1310320 :         for ( c = 0; c < h->num_channels; ++c )
     217             :         {
     218      660656 :             h->data[h->write_pos] = 0.f;
     219      660656 :             ++h->write_pos;
     220             : 
     221      660656 :             if ( h->write_pos == h->capacity )
     222             :             {
     223           0 :                 h->write_pos = 0;
     224             :             }
     225             :         }
     226             :     }
     227             : 
     228        5584 :     if ( h->read_pos == h->write_pos )
     229             :     {
     230           0 :         h->is_full = 1;
     231             :     }
     232             : 
     233        5584 :     return;
     234             : }
     235             : 
     236             : 
     237             : /*---------------------------------------------------------------------*
     238             :  * ivas_TD_RINGBUF_Pop()
     239             :  *
     240             :  * Pop samples from the front of the TD ring buffer.
     241             :  *---------------------------------------------------------------------*/
     242             : 
     243     5093816 : void ivas_TD_RINGBUF_Pop(
     244             :     TD_RINGBUF_HANDLE h,                   /* i/o: Ring buffer handle                           */
     245             :     float *data,                           /* i  : Output data                                  */
     246             :     const uint32_t num_samples_per_channel /* i  : Number of samples per channel to retrieve    */
     247             : )
     248             : {
     249             :     uint32_t s;
     250             :     uint16_t c;
     251             : 
     252     5093816 :     assert( ivas_td_ringbuf_total_size( h ) >= num_samples_per_channel * h->num_channels );
     253             : 
     254  1595650680 :     for ( s = 0; s < num_samples_per_channel; ++s )
     255             :     {
     256 11197995120 :         for ( c = 0; c < h->num_channels; ++c )
     257             :         {
     258  9607438256 :             *( data + c * num_samples_per_channel + s ) = h->data[h->read_pos];
     259  9607438256 :             ++h->read_pos;
     260             : 
     261  9607438256 :             if ( h->read_pos == h->capacity )
     262             :             {
     263     2233288 :                 h->read_pos = 0;
     264             :             }
     265             :         }
     266             :     }
     267             : 
     268     5093816 :     if ( h->is_full )
     269             :     {
     270           0 :         h->is_full = 0;
     271             :     }
     272             : 
     273     5093816 :     return;
     274             : }
     275             : 
     276             : 
     277             : /*---------------------------------------------------------------------*
     278             :  * ivas_TD_RINGBUF_Size()
     279             :  *
     280             :  * Returns number of buffered samples per channel.
     281             :  *---------------------------------------------------------------------*/
     282             : 
     283        5584 : uint32_t ivas_TD_RINGBUF_Size(
     284             :     const TD_RINGBUF_HANDLE h /* i  : Ring buffer handle */
     285             : )
     286             : {
     287        5584 :     return ivas_td_ringbuf_total_size( h ) / (uint32_t) h->num_channels;
     288             : }

Generated by: LCOV version 1.14