diff options
Diffstat (limited to 'src/audio/audio_rx.h')
-rw-r--r-- | src/audio/audio_rx.h | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/src/audio/audio_rx.h b/src/audio/audio_rx.h new file mode 100644 index 0000000..5db8762 --- /dev/null +++ b/src/audio/audio_rx.h @@ -0,0 +1,217 @@ +/* + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _AUDIO_RX_H +#define _AUDIO_RX_H + +// Receive audio from the soundcard and send it to the RTP thread. + +#include <assert.h> +#include <queue> +#include <string> + +#include "audio_codecs.h" +#include "audio_device.h" +#include "audio_encoder.h" +#include "dtmf_player.h" +#include "media_buffer.h" +#include "user.h" +#include "threads/mutex.h" +#include "threads/sema.h" +#include "twinkle_rtp_session.h" +#include "twinkle_config.h" + +#ifdef HAVE_SPEEX +#include <speex/speex.h> +#include <speex/speex_preprocess.h> +#endif + +using namespace std; +using namespace ost; + +// Forward declarations +class t_audio_session; +class t_line; + +class t_audio_rx { +private: + // audio_session owning this audio receiver + t_audio_session *audio_session; + + // User profile of user using the line + // This is a pointer to the user_config owned by a phone user. + // So this pointer should never be deleted. + t_user *user_config; + + // file descriptor audio capture device + t_audio_io* input_device; + + // RTP session + t_twinkle_rtp_session *rtp_session; + + // Media buffer to buffer media from the peer audio trasmitter in a + // 3-way call. This media stream will be mixed with the + // audio captured from the soundcard. + t_media_buffer *media_3way_peer_tx; + + // Media captured by the peer audio receiver in a 3-way conference + t_media_buffer *media_3way_peer_rx; + + // The peer audio receiver in a 3-way conference. + t_audio_rx *peer_rx_3way; + + // Buffer for mixing purposes in 3-way conference. + unsigned char *mix_buf_3way; + + // Indicates if this receiver is part of a 3-way conference call + bool is_3way; + + // Indicates if this is this receiver has to capture sound from the + // soundcard. In a 3-way call, one receiver captures sound, while the + // other receiver simply takes the sound from the main receiver. + bool is_main_rx_3way; + + // Mutex to protect actions on 3-way conference data + t_mutex mtx_3way; + + // Audio encoder + t_audio_encoder *audio_encoder; + + // Buffer to store PCM samples for ptime ms + unsigned char *input_sample_buf; + + // Indicates if NAT keep alive packets must be sent during silence + // suppression. + bool use_nat_keepalive; + + // RTP payload + unsigned short payload_size; + unsigned char *payload; + unsigned short nsamples; // number of samples taken per packet + + // Payload type for telephone-event payload. + int pt_telephone_event; + + // Queue of DTMF tones to be sent + struct t_dtmf_event { + uint8 dtmf_tone; + bool inband; + }; + + queue<t_dtmf_event> dtmf_queue; + t_mutex mtx_dtmf_q; + t_semaphore sema_dtmf_q; + + // DTMF player + t_dtmf_player *dtmf_player; + + // Inidicates if the recording thread is running + volatile bool is_running; + + // The thread exits when this indicator is set to true + volatile bool stop_running; + + // Indicates if a capture failure was already logged (log throttling). + bool logged_capture_failure; + + // Timestamp for next RTP packet + unsigned long timestamp; + +#ifdef HAVE_SPEEX + /** Speex preprocessor state */ + SpeexPreprocessState *speex_preprocess_state; + + /** Speex VAD enabled? */ + bool speex_dsp_vad; +#endif + + // Get sound samples for 1 RTP packet from the soundcard. + // Returns false if the main loop has to start another cycle to get + // samples (eg. no samples available yet). + // If not enough samples are available yet, then a 1 ms sleep will be taken. + // Also returns false if capturing samples from the soundcard failed. + // Returns true if sounds samples are received. The samples are stored + // in the payload buffer in the proper encoding. + // The number bytes of the sound payload is returned in sound_payload_size + // The silence flag indicates if the returned sound samples represent silence + // that may be suppressed. + bool get_sound_samples(unsigned short &sound_payload_size, bool &silence); + + // Get next DTMF event generated by the user. + // Returns false if there is no next DTMF event + bool get_dtmf_event(void); + + // Set RTP payload for outgoing sound packets based on the codec. + void set_sound_payload_format(void); + +public: + // Create the audio receiver + // _fd file descriptor of capture device + // _rtp_session RTP socket tp send the RTP stream + // _codec audio codec to use + // _ptime length of the audio packets in ms + // _ptime = 0 means use default ptime value for the codec + t_audio_rx(t_audio_session *_audio_session, t_audio_io *_input_device, + t_twinkle_rtp_session *_rtp_session, + t_audio_codec _codec, unsigned short _payload_id, + unsigned short _ptime = 0); + + ~t_audio_rx(); + + // Set the is running flag + void set_running(bool running); + + void run(void); + + // Set the dynamic payload type for telephone events + void set_pt_telephone_event(int pt); + + // Push a new DTMF tone in the DTMF queue + void push_dtmf(char digit, bool inband); + + // Get phone line belonging to this audio transmitter + t_line *get_line(void) const; + + // Join a 3-way conference call. + // main_rx indicates if this receiver must be the main receiver capturing + // the sound from the soundcard. + // The peer_rx is the peer receiver (may be NULL( + void join_3way(bool main_rx, t_audio_rx *peer_rx); + + // Change the peer receiver in a 3-way (set to NULL to erase). + void set_peer_rx_3way(t_audio_rx *peer_rx); + + // Change the main rx role in a 3-way + void set_main_rx_3way(bool main_rx); + + // Delete 3rd party from a 3-way conference. + void stop_3way(void); + + // Post media from the peer transmitter in a 3-way. + void post_media_peer_tx_3way(unsigned char *media, int len, + unsigned short peer_sample_rate); + + // Post media from the peer receiver in a 3-way. + void post_media_peer_rx_3way(unsigned char *media, int len, + unsigned short peer_sample_rate); + + // Returns if this receiver is the main receiver in a 3-way + bool get_is_main_rx_3way(void) const; +}; + +#endif |