/* Copyright (C) 2005-2009 Michel de Boer 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 . */ #ifndef _AUDIO_RX_H #define _AUDIO_RX_H // Receive audio from the soundcard and send it to the RTP thread. #include #include #include #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 #include #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 { t_dtmf_ev dtmf_tone; bool inband; }; queue 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