summaryrefslogtreecommitdiffstats
path: root/src/audio/audio_session.h
blob: 1e01ce01665e6943f770e3217801b962329e66d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
    Copyright (C) 2005-2009  Michel de Boer <michel@twinklephone.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef _AUDIO_SESSION_H
#define _AUDIO_SESSION_H

#include <map>
#include <string>
#include "audio_rx.h"
#include "audio_tx.h"
#include "session.h"
#include "twinkle_rtp_session.h"
#include "threads/thread.h"
#include "threads/mutex.h"

#ifdef HAVE_SPEEX
#include <speex/speex_echo.h> 
#endif

using namespace std;
using namespace ost;

// Forward declarations
class t_session;
class t_line;

class t_audio_session {
private:
	// SIP session owning this audio session
	t_session	*session;
	
	/** Mutex for concurrent access to the session. */
	mutable t_mutex	mtx_session;

	// This flag indicates if the created audio session is valid.
	// It might be invalid because, the RTP session could not be created
	// or the soundcard could not be opened.
	bool		valid;

	// file descriptor audio device
	t_audio_io		*speaker;
	t_audio_io		*mic;
	t_twinkle_rtp_session   *rtp_session;

	t_audio_codec	codec;
	unsigned short	ptime;	// in milliseconds

	t_thread	*thr_audio_rx; // recording thread
	t_thread	*thr_audio_tx; // playing thread
	
	// ZRTP info
	mutable t_mutex	mtx_zrtp_data;
	bool		is_encrypted;
	string		zrtp_sas;
	bool		zrtp_sas_confirmed;
	string		srtp_cipher_mode;

#ifdef HAVE_SPEEX
	// Indicator whether to use (Speex) AEC 
	bool do_echo_cancellation;

	// Indicator whether the last operation of (Speex) AEC,
	// speex_echo_capture or speex_echo_playback, was the speex_echo_capture
	bool echo_captured_last;

	// speex AEC state 
	SpeexEchoState *speex_echo_state;
#endif

	// 3-way conference data
	// Returns if this audio session is part of a 3-way conference
	bool is_3way(void) const;

	// Returns the peer audio session of a 3-way conference
	t_audio_session *get_peer_3way(void) const;

	// Open the sound card
	bool open_dsp(void);
	bool open_dsp_full_duplex(void);
	bool open_dsp_speaker(void);
	bool open_dsp_mic(void);

public:

	t_audio_rx	*audio_rx;
	t_audio_tx	*audio_tx;


	t_audio_session(t_session *_session,
			const string &_recv_host, unsigned short _recv_port,
		        const string &_dst_host, unsigned short _dst_port,
			t_audio_codec _codec, unsigned short _ptime,
			const map<unsigned short, t_audio_codec> &recv_payload2ac,
			const map<t_audio_codec, unsigned short> &send_ac2payload,
			bool encrypt);

	~t_audio_session();

	void run(void);
	
	/**
	 * Change the owning session.
	 * @param _session New session owning this audio session.
	 */
	void set_session(t_session *_session);

	// Set outgoing/incoming DTMF dynamic payload types
	void set_pt_out_dtmf(unsigned short pt);
	void set_pt_in_dtmf(unsigned short pt, unsigned short pt_alt);

	// Send DTMF digit
	void send_dtmf(char digit, bool inband);

	// Get the line that belongs to this audio session
	t_line *get_line(void) const;

	// Become the first session in a 3-way conference
	void start_3way(void);

	// Leave a 3-way conference
	void stop_3way(void);

	// Check if audio session is valid
	bool is_valid(void) const;

	// Get pointer for soundcard I/O object
	t_audio_io* get_dsp_speaker(void) const;
	t_audio_io* get_dsp_mic(void) const;
	
	// Check if sample rate from speaker and mic match with sample rate
	// from codec. The sample rates might not match due to 3-way conference
	// calls with mixed sample rate
	bool matching_sample_rates(void) const;
	
	// ZRTP actions
	void confirm_zrtp_sas(void);
	void reset_zrtp_sas_confirmation(void);
	void enable_zrtp(void);
	void zrtp_request_go_clear(void);
	void zrtp_go_clear_ok(void);
	
	// ZRTP data manipulations
	bool get_is_encrypted(void) const;
	string get_zrtp_sas(void) const;
	bool get_zrtp_sas_confirmed(void) const;
	string get_srtp_cipher_mode(void) const;
	
	void set_is_encrypted(bool on);
	void set_zrtp_sas(const string &sas);
	void set_zrtp_sas_confirmed(bool confirmed);
	void set_srtp_cipher_mode(const string &cipher_mode);

#ifdef HAVE_SPEEX
	// speex acoustic echo cancellation (AEC) manipulations
	bool get_do_echo_cancellation(void) const;
	bool get_echo_captured_last(void);
	void set_echo_captured_last(bool value);
	SpeexEchoState *get_speex_echo_state(void);
#endif
	
};

// Main functions for rx and tx threads
void *main_audio_rx(void *arg);
void *main_audio_tx(void *arg);

#endif