Ring Daemon
Loading...
Searching...
No Matches
dtmfgenerator.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2026 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
23namespace jami {
24
27{
28 unsigned char code;
29 unsigned lower;
30 unsigned higher;
31};
32
33/*
34 * Tone frequencies
35 */
36constexpr DTMFTone TONES[] = {{'0', 941, 1336},
37 {'1', 697, 1209},
38 {'2', 697, 1336},
39 {'3', 697, 1477},
40 {'4', 770, 1209},
41 {'5', 770, 1336},
42 {'6', 770, 1477},
43 {'7', 852, 1209},
44 {'8', 852, 1336},
45 {'9', 852, 1477},
46 {'A', 697, 1633},
47 {'B', 770, 1633},
48 {'C', 852, 1633},
49 {'D', 941, 1633},
50 {'*', 941, 1209},
51 {'#', 941, 1477}};
52
53/*
54 * Initialize the generator
55 */
56DTMFGenerator::DTMFGenerator(unsigned int sampleRate, AVSampleFormat sampleFormat)
57 : state()
58 , sampleRate_(sampleRate)
59 , tone_("", sampleRate, sampleFormat)
60{
61 state.offset = 0;
62 state.sample = 0;
63
64 for (int i = 0; i < NUM_TONES; i++)
65 toneBuffers_[i] = fillToneBuffer(i);
66}
67
69
70void
72{
73 code = toupper(code);
74
75 if (code >= '0' and code <= '9')
76 state.sample = toneBuffers_[code - '0'].get();
77 else if (code >= 'A' and code <= 'D')
78 state.sample = toneBuffers_[code - 'A' + 10].get();
79 else {
80 switch (code) {
81 case '*':
82 state.sample = toneBuffers_[NUM_TONES - 2].get();
83 break;
84
85 case '#':
86 state.sample = toneBuffers_[NUM_TONES - 1].get();
87 break;
88
89 default:
90 throw DTMFException("Invalid code");
91 break;
92 }
93 }
94
96 state.sample->data,
97 0,
98 state.offset,
99 frame->nb_samples,
100 frame->ch_layout.nb_channels,
101 (AVSampleFormat) frame->format);
102 state.offset = frame->nb_samples % sampleRate_;
103}
104
105/*
106 * Get next n samples (continues where previous call to
107 * genSample or genNextSamples stopped
108 */
109void
111{
112 if (state.sample == 0)
113 throw DTMFException("DTMF generator not initialized");
114
116 state.sample->data,
117 0,
118 state.offset,
119 frame->nb_samples,
120 frame->ch_layout.nb_channels,
121 (AVSampleFormat) frame->format);
122 state.offset = (state.offset + frame->nb_samples) % sampleRate_;
123}
124
126DTMFGenerator::fillToneBuffer(unsigned index)
127{
128 assert(index < NUM_TONES);
130 ptr->nb_samples = sampleRate_;
131 ptr->format = tone_.getFormat().sampleFormat;
132 ptr->sample_rate = sampleRate_;
133 ptr->channel_layout = AV_CH_LAYOUT_MONO;
135 av_frame_get_buffer(ptr.get(), 0);
136 tone_.genSin(ptr.get(), 0, ptr->nb_samples, TONES[index].higher, TONES[index].lower);
137 return ptr;
138}
139
140} // namespace jami
AudioFormat getFormat() const
Definition audioloop.h:73
void getNextSamples(AVFrame *frame)
DTMFGenerator(unsigned int sampleRate, AVSampleFormat sampleFormat)
DTMF Generator contains frequency of each keys and can build one DTMF.
void getSamples(AVFrame *frame, unsigned char code)
static void genSin(AVFrame *buffer, size_t outPos, unsigned nb_samples, unsigned frequency1, unsigned frequency2)
Add a simple or double sin to the buffer, it double the sin in stereo.
Definition tone.cpp:111
#define NUM_TONES
void emitSignal(Args... args)
Definition jami_signal.h:64
constexpr DTMFTone TONES[]
std::unique_ptr< AVFrame, AVFrame_deleter > FrameBuffer
AVSampleFormat sampleFormat
Struct to handle a DTMF.
unsigned higher
Lower frequency.
unsigned lower
Code of the tone.
unsigned char code