LCOV - code coverage report
Current view: top level - src/media/audio - audioloop.cpp (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 12.8 % 47 6
Test Date: 2026-06-13 09:18:46 Functions: 15.4 % 13 2

            Line data    Source code
       1              : /*
       2              :  *  Copyright (C) 2004-2026 Savoir-faire Linux Inc.
       3              :  *
       4              :  *  Inspired by tonegenerator of
       5              :  *   Laurielle Lea <laurielle.lea@savoirfairelinux.com> (2004)
       6              :  *  Inspired by ringbuffer of Audacity Project
       7              :  *
       8              :  *  This program is free software: you can redistribute it and/or modify
       9              :  *  it under the terms of the GNU General Public License as published by
      10              :  *  the Free Software Foundation, either version 3 of the License, or
      11              :  *  (at your option) any later version.
      12              :  *
      13              :  *  This program is distributed in the hope that it will be useful,
      14              :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      15              :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      16              :  *  GNU General Public License for more details.
      17              :  *
      18              :  *  You should have received a copy of the GNU General Public License
      19              :  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
      20              :  */
      21              : 
      22              : #ifdef HAVE_CONFIG_H
      23              : #include "config.h"
      24              : #endif
      25              : 
      26              : #include "audioloop.h"
      27              : #include "logger.h"
      28              : #include "libav_deps.h"
      29              : 
      30              : #include <algorithm> // std::min
      31              : 
      32              : namespace jami {
      33              : 
      34          435 : AudioLoop::AudioLoop(AudioFormat format)
      35          435 :     : format_(format)
      36          435 :     , buffer_(av_frame_alloc())
      37          435 :     , pos_(0)
      38          435 : {}
      39              : 
      40          435 : AudioLoop::~AudioLoop() {}
      41              : 
      42              : void
      43            0 : AudioLoop::seek(double relative_position)
      44              : {
      45            0 :     pos_ = static_cast<size_t>(static_cast<double>(getSize()) * relative_position * 0.01);
      46            0 : }
      47              : 
      48              : void
      49            0 : AudioLoop::getNext(AVFrame* output, bool mute)
      50              : {
      51            0 :     if (!buffer_) {
      52            0 :         JAMI_ERROR("buffer is NULL");
      53            0 :         return;
      54              :     }
      55              : 
      56            0 :     const size_t buf_samples = buffer_->nb_samples;
      57            0 :     size_t pos = pos_;
      58            0 :     size_t total_samples = output->nb_samples;
      59            0 :     size_t output_pos = 0;
      60              : 
      61            0 :     if (buf_samples == 0) {
      62            0 :         JAMI_ERROR("Audio loop size is 0");
      63            0 :         av_samples_set_silence(output->data,
      64              :                                0,
      65              :                                output->nb_samples,
      66            0 :                                static_cast<int>(format_.nb_channels),
      67              :                                format_.sampleFormat);
      68            0 :         return;
      69            0 :     } else if (pos >= buf_samples) {
      70            0 :         JAMI_ERROR("Invalid loop position {}", pos);
      71            0 :         return;
      72              :     }
      73              : 
      74            0 :     while (total_samples != 0) {
      75            0 :         size_t samples = std::min(total_samples, buf_samples - pos);
      76            0 :         if (not mute)
      77            0 :             av_samples_copy(output->data,
      78            0 :                             buffer_->data,
      79              :                             static_cast<int>(output_pos),
      80              :                             static_cast<int>(pos),
      81              :                             static_cast<int>(samples),
      82            0 :                             static_cast<int>(format_.nb_channels),
      83              :                             format_.sampleFormat);
      84              :         else
      85            0 :             av_samples_set_silence(output->data,
      86              :                                    static_cast<int>(output_pos),
      87              :                                    static_cast<int>(samples),
      88            0 :                                    static_cast<int>(format_.nb_channels),
      89              :                                    format_.sampleFormat);
      90            0 :         output_pos += samples;
      91            0 :         pos = (pos + samples) % buf_samples;
      92            0 :         total_samples -= samples;
      93              :     }
      94              : 
      95            0 :     pos_ = pos;
      96            0 :     onBufferFinish();
      97              : }
      98              : 
      99              : void
     100            0 : AudioLoop::onBufferFinish()
     101            0 : {}
     102              : 
     103              : std::unique_ptr<AudioFrame>
     104            0 : AudioLoop::getNext(size_t samples, bool mute)
     105              : {
     106            0 :     if (samples == 0) {
     107            0 :         samples = buffer_->sample_rate / 50;
     108              :     }
     109            0 :     auto buffer = std::make_unique<AudioFrame>(format_, samples);
     110            0 :     getNext(buffer->pointer(), mute);
     111            0 :     return buffer;
     112            0 : }
     113              : 
     114              : } // namespace jami
        

Generated by: LCOV version 2.0-1