LCOV - code coverage report
Current view: top level - src/media/audio/sound - dtmfgenerator.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 22 47 46.8 %
Date: 2024-12-21 08:56:24 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /*
       2             :  *  Copyright (C) 2004-2024 Savoir-faire Linux Inc.
       3             :  *
       4             :  *  This program is free software: you can redistribute it and/or modify
       5             :  *  it under the terms of the GNU General Public License as published by
       6             :  *  the Free Software Foundation, either version 3 of the License, or
       7             :  *  (at your option) any later version.
       8             :  *
       9             :  *  This program is distributed in the hope that it will be useful,
      10             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      12             :  *  GNU General Public License for more details.
      13             :  *
      14             :  *  You should have received a copy of the GNU General Public License
      15             :  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
      16             :  */
      17             : #include "dtmfgenerator.h"
      18             : #include "libav_deps.h"
      19             : 
      20             : #include <cmath>
      21             : #include <cassert>
      22             : #include <ciso646> // fix windows compiler bug
      23             : 
      24             : namespace jami {
      25             : 
      26             : /*
      27             :  * Tone frequencies
      28             :  */
      29             : const DTMFGenerator::DTMFTone DTMFGenerator::tones_[] = {{'0', 941, 1336},
      30             :                                                          {'1', 697, 1209},
      31             :                                                          {'2', 697, 1336},
      32             :                                                          {'3', 697, 1477},
      33             :                                                          {'4', 770, 1209},
      34             :                                                          {'5', 770, 1336},
      35             :                                                          {'6', 770, 1477},
      36             :                                                          {'7', 852, 1209},
      37             :                                                          {'8', 852, 1336},
      38             :                                                          {'9', 852, 1477},
      39             :                                                          {'A', 697, 1633},
      40             :                                                          {'B', 770, 1633},
      41             :                                                          {'C', 852, 1633},
      42             :                                                          {'D', 941, 1633},
      43             :                                                          {'*', 941, 1209},
      44             :                                                          {'#', 941, 1477}};
      45             : 
      46             : /*
      47             :  * Initialize the generator
      48             :  */
      49          33 : DTMFGenerator::DTMFGenerator(unsigned int sampleRate, AVSampleFormat sampleFormat)
      50          33 :     : state()
      51          33 :     , sampleRate_(sampleRate)
      52          33 :     , tone_("", sampleRate, sampleFormat)
      53             : {
      54          33 :     state.offset = 0;
      55          33 :     state.sample = 0;
      56             : 
      57         561 :     for (int i = 0; i < NUM_TONES; i++)
      58         528 :         toneBuffers_[i] = fillToneBuffer(i);
      59          33 : }
      60             : 
      61          33 : DTMFGenerator::~DTMFGenerator()
      62          33 : {}
      63             : 
      64             : using std::vector;
      65             : 
      66           0 : void DTMFGenerator::getSamples(AVFrame* frame, unsigned char code) {
      67           0 :     code = toupper(code);
      68             : 
      69           0 :     if (code >= '0' and code <= '9')
      70           0 :         state.sample = toneBuffers_[code - '0'].get();
      71           0 :     else if (code >= 'A' and code <= 'D')
      72           0 :         state.sample = toneBuffers_[code - 'A' + 10].get();
      73             :     else {
      74           0 :         switch (code) {
      75           0 :         case '*':
      76           0 :             state.sample = toneBuffers_[NUM_TONES - 2].get();
      77           0 :             break;
      78             : 
      79           0 :         case '#':
      80           0 :             state.sample = toneBuffers_[NUM_TONES - 1].get();
      81           0 :             break;
      82             : 
      83           0 :         default:
      84           0 :             throw DTMFException("Invalid code");
      85             :             break;
      86             :         }
      87             :     }
      88             : 
      89           0 :     av_samples_copy(frame->data, state.sample->data, 0, state.offset, frame->nb_samples, frame->ch_layout.nb_channels, (AVSampleFormat)frame->format);
      90           0 :     state.offset = frame->nb_samples % sampleRate_;
      91           0 : }
      92             : 
      93             : /*
      94             :  * Get next n samples (continues where previous call to
      95             :  * genSample or genNextSamples stopped
      96             :  */
      97           0 : void DTMFGenerator::getNextSamples(AVFrame* frame) {
      98           0 :     if (state.sample == 0)
      99           0 :         throw DTMFException("DTMF generator not initialized");
     100             : 
     101           0 :     av_samples_copy(frame->data, state.sample->data, 0, state.offset, frame->nb_samples, frame->ch_layout.nb_channels, (AVSampleFormat)frame->format);
     102           0 :     state.offset = (state.offset + frame->nb_samples) % sampleRate_;
     103           0 : }
     104             : 
     105             : 
     106             : libjami::FrameBuffer
     107         528 : DTMFGenerator::fillToneBuffer(int index)
     108             : {
     109         528 :     assert(index >= 0 and index < NUM_TONES);
     110         528 :     libjami::FrameBuffer ptr(av_frame_alloc());
     111         528 :     ptr->nb_samples = sampleRate_;
     112         528 :     ptr->format = tone_.getFormat().sampleFormat;
     113         528 :     ptr->sample_rate = sampleRate_;
     114         528 :     ptr->channel_layout = AV_CH_LAYOUT_MONO;
     115         528 :     av_channel_layout_from_mask(&ptr->ch_layout, AV_CH_LAYOUT_MONO);
     116         528 :     av_frame_get_buffer(ptr.get(), 0);
     117         528 :     tone_.genSin(ptr.get(), 0, ptr->nb_samples, tones_[index].higher, tones_[index].lower);
     118         528 :     return ptr;
     119           0 : }
     120             : 
     121             : } // namespace jami

Generated by: LCOV version 1.14