FreeSWITCH API Documentation  1.7.0
libteletone_generate.h
Go to the documentation of this file.
1 /*
2  * libteletone
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is libteletone
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  *
28  *
29  * libteletone.h -- Tone Generator
30  *
31  *
32  *
33  * Exception:
34  * The author hereby grants the use of this source code under the
35  * following license if and only if the source code is distributed
36  * as part of the OpenZAP or FreeTDM library. Any use or distribution of this
37  * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
38  * following license and reinact the MPL 1.1 as stated above.
39  *
40  * Copyright (c) 2007, Anthony Minessale II
41  * All rights reserved.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  *
47  * * Redistributions of source code must retain the above copyright
48  * notice, this list of conditions and the following disclaimer.
49  *
50  * * Redistributions in binary form must reproduce the above copyright
51  * notice, this list of conditions and the following disclaimer in the
52  * documentation and/or other materials provided with the distribution.
53  *
54  * * Neither the name of the original author; nor the names of any contributors
55  * may be used to endorse or promote products derived from this software
56  * without specific prior written permission.
57  *
58  *
59  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
60  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
61  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
62  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
63  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
64  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
65  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
66  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
67  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
68  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70  */
71 #ifndef LIBTELETONE_GENERATE_H
72 #define LIBTELETONE_GENERATE_H
73 #ifdef __cplusplus
74 extern "C" {
75 #ifdef _doh
76 }
77 #endif
78 #endif
79 
80 #include <stdio.h>
81 #include <stdlib.h>
82 
83 #if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
84 #ifndef __inline__
85 #define __inline__ inline
86 #endif
87 #endif
88 
89 #ifdef _MSC_VER
90 #ifndef __inline__
91 #define __inline__ __inline
92 #endif
93 
94 #if !defined(_STDINT) && !defined(uint32_t)
95 typedef unsigned __int64 uint64_t;
96 typedef unsigned __int32 uint32_t;
97 typedef unsigned __int16 uint16_t;
98 typedef unsigned __int8 uint8_t;
99 typedef __int64 int64_t;
100 typedef __int32 int32_t;
101 typedef __int16 int16_t;
102 typedef __int8 int8_t;
103 #endif
104 #else
105 #include <stdint.h>
106 #endif
107 #include <sys/types.h>
108 #include <sys/stat.h>
109 #include <fcntl.h>
110 #include <math.h>
111 #if !defined(powf) && !defined(_WIN64)
112 #ifdef _MSC_VER
113 #pragma warning(push)
114 #pragma warning(disable: 28251)
115 #endif
116 extern float powf (float, float);
117 #ifdef _MSC_VER
118 #pragma warning(pop)
119 #endif
120 #endif
121 #include <string.h>
122 #include <errno.h>
123 #ifndef _MSC_VER
124 #include <unistd.h>
125 #endif
126 #include <assert.h>
127 #include <stdarg.h>
128 #include <libteletone.h>
129 
130 #define TELETONE_VOL_DB_MAX 0
131 #define TELETONE_VOL_DB_MIN -63
132 #define MAX_PHASE_TONES 4
133 
136  uint32_t scale_factor;
139 };
141 
142 #define SINE_TABLE_MAX 128
143 #define SINE_TABLE_LEN (SINE_TABLE_MAX - 1)
144 #define MAX_PHASE_ACCUMULATOR 0x10000 * 0x10000
145 /* 3.14 == the max power on ulaw (alaw is 3.17) */
146 /* 3.02 represents twice the power */
147 #define DBM0_MAX_POWER (3.14f + 3.02f)
148 
150 
151 static __inline__ int32_t teletone_dds_phase_rate(teletone_process_t tone, uint32_t rate)
152 {
153  return (int32_t) ((tone * MAX_PHASE_ACCUMULATOR) / rate);
154 }
155 
156 static __inline__ int16_t teletone_dds_state_modulate_sample(teletone_dds_state_t *dds, uint32_t pindex)
157 {
158  int32_t bitmask = dds->phase_accumulator, sine_index = (bitmask >>= 23) & SINE_TABLE_LEN;
159  int16_t sample;
160 
161  if (pindex >= MAX_PHASE_TONES) {
162  pindex = 0;
163  }
164 
165  if (bitmask & SINE_TABLE_MAX) {
166  sine_index = SINE_TABLE_LEN - sine_index;
167  }
168 
169  sample = TELETONE_SINES[sine_index];
170 
171  if (bitmask & (SINE_TABLE_MAX * 2)) {
172  sample *= -1;
173  }
174 
175  dds->phase_accumulator += dds->phase_rate[pindex];
176  return (int16_t) (sample * dds->scale_factor >> 15);
177 }
178 
180 {
181  dds->scale_factor = (int) (powf(10.0f, (tx_level - DBM0_MAX_POWER) / 20.0f) * (32767.0f * 1.414214f));
182  dds->tx_level = tx_level;
183 }
184 
186 {
187  dds->phase_accumulator = 0;
188 }
189 
190 static __inline__ int teletone_dds_state_set_tone(teletone_dds_state_t *dds, teletone_process_t tone, uint32_t rate, uint32_t pindex)
191 {
192  if (pindex < MAX_PHASE_TONES) {
193  dds->phase_rate[pindex] = teletone_dds_phase_rate(tone, rate);
194  return 0;
195  }
196 
197  return -1;
198 }
199 
200 
201 
202 /*! \file libteletone_generate.h
203  \brief Tone Generation Routines
204 
205  This module is responsible for tone generation specifics
206 */
207 
208 typedef int16_t teletone_audio_t;
211 
212 /*! \brief An abstraction to store a tone generation session */
214  /*! An array of tone mappings to character mappings */
216  /*! The number of channels the output audio should be in */
217  int channels;
218  /*! The Rate in hz of the output audio */
219  int rate;
220  /*! The duration (in samples) of the output audio */
221  int duration;
222  /*! The duration of silence to append after the initial audio is generated */
223  int wait;
224  /*! The duration (in samples) of the output audio (takes prescedence over actual duration value) */
226  /*! The duration of silence to append after the initial audio is generated (takes prescedence over actual wait value)*/
227  int tmp_wait;
228  /*! Number of loops to repeat a single instruction*/
229  int loops;
230  /*! Number of loops to repeat the entire set of instructions*/
231  int LOOPS;
232  /*! Number to mutiply total samples by to determine when to begin ascent or decent e.g. 0=beginning 4=(last 25%) */
234  /*! Direction to perform volume increase/decrease 1/-1*/
236  /*! Number of samples between increase/decrease of volume */
238  /*! Volume factor of the tone */
239  float volume;
240  /*! Debug on/off */
241  int debug;
242  /*! FILE stream to write debug data to */
244  /*! Extra user data to attach to the session*/
245  void *user_data;
246  /*! Buffer for storing sample data (dynamic) */
248  /*! Size of the buffer */
249  int datalen;
250  /*! In-Use size of the buffer */
251  int samples;
252  /*! Callback function called during generation */
253  int dynamic;
255 };
256 
258 
259 
260 /*!
261  \brief Assign a set of tones to a tone_session indexed by a paticular index/character
262  \param ts the tone generation session
263  \param index the index to map the tone to
264  \param ... up to TELETONE_MAX_TONES frequencies terminated by 0.0
265  \return 0
266 */
268 
269 /*!
270  \brief Assign a set of tones to a single tone map
271  \param map the map to assign the tones to
272  \param ... up to TELETONE_MAX_TONES frequencies terminated by 0.0
273  \return 0
274 */
276 
277 /*!
278  \brief Initilize a tone generation session
279  \param ts the tone generation session to initilize
280  \param buflen the size of the buffer(in samples) to dynamically allocate
281  \param handler a callback function to execute when a tone generation instruction is complete
282  \param user_data optional user data to send
283  \return 0
284 */
286 
287 /*!
288  \brief Free the buffer allocated by a tone generation session
289  \param ts the tone generation session to destroy
290  \return 0
291 */
293 
294 /*!
295  \brief Execute a single tone generation instruction
296  \param ts the tone generation session to consult for parameters
297  \param map the tone mapping to use for the frequencies
298  \return 0
299 */
301 
302 /*!
303  \brief Execute a tone generation script and call callbacks after each instruction
304  \param ts the tone generation session to execute on
305  \param cmd the script to execute
306  \return 0
307 */
308 TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd);
309 
310 #ifdef __cplusplus
311 }
312 #endif
313 
314 #endif
315 
316 /* For Emacs:
317  * Local Variables:
318  * mode:c
319  * indent-tabs-mode:t
320  * tab-width:4
321  * c-basic-offset:4
322  * End:
323  * For VIM:
324  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
325  */
#define TELETONE_API_DATA
Definition: libteletone.h:135
static __inline__ int16_t teletone_dds_state_modulate_sample(teletone_dds_state_t *dds, uint32_t pindex)
An abstraction to store a tone mapping.
Definition: libteletone.h:93
uint32_t phase_rate[MAX_PHASE_TONES]
double teletone_process_t
Definition: libteletone.h:84
#define DBM0_MAX_POWER
static __inline__ int teletone_dds_state_set_tone(teletone_dds_state_t *dds, teletone_process_t tone, uint32_t rate, uint32_t pindex)
#define TELETONE_API(type)
Definition: libteletone.h:133
int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map)
Execute a single tone generation instruction.
int teletone_destroy_session(teletone_generation_session_t *ts)
Free the buffer allocated by a tone generation session.
int teletone_set_map(teletone_tone_map_t *map,...)
Assign a set of tones to a single tone map.
teletone_tone_map_t TONES[TELETONE_TONE_RANGE]
teletone_process_t tx_level
#define MAX_PHASE_ACCUMULATOR
#define SINE_TABLE_LEN
static __inline__ void teletone_dds_state_set_tx_level(teletone_dds_state_t *dds, float tx_level)
int teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data)
Initilize a tone generation session.
int teletone_run(teletone_generation_session_t *ts, const char *cmd)
Execute a tone generation script and call callbacks after each instruction.
switch_byte_t switch_byte_t uint32_t buflen
Top level include file.
static __inline__ int32_t teletone_dds_phase_rate(teletone_process_t tone, uint32_t rate)
int16_t teletone_audio_t
#define TELETONE_TONE_RANGE
Definition: libteletone.h:82
float powf(float, float)
#define MAX_PHASE_TONES
static __inline__ void teletone_dds_state_reset_accum(teletone_dds_state_t *dds)
An abstraction to store a tone generation session.
int(* tone_handler)(struct teletone_generation_session *ts, teletone_tone_map_t *map)
int16_t TELETONE_SINES[SINE_TABLE_MAX]
#define SINE_TABLE_MAX
int teletone_set_tone(teletone_generation_session_t *ts, int index,...)
Assign a set of tones to a tone_session indexed by a paticular index/character.