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-04-25 08:05:53 Functions: 3 5 60.0 %

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

Generated by: LCOV version 1.14