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
|