diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 02:13:59 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 02:13:59 +0000 |
commit | a6d58bb6052ac8cb01805a48c4ad2f129126116f (patch) | |
tree | dd867a099fcbb263a8009a9fb22695b87855dad6 /src/modules/dcc/voice.h | |
download | kvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.tar.gz kvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.zip |
Added KDE3 version of kvirc
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kvirc@1095341 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/modules/dcc/voice.h')
-rw-r--r-- | src/modules/dcc/voice.h | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/src/modules/dcc/voice.h b/src/modules/dcc/voice.h new file mode 100644 index 00000000..c74c677c --- /dev/null +++ b/src/modules/dcc/voice.h @@ -0,0 +1,440 @@ +#ifndef _VOICE_H_ +#define _VOICE_H_ +// +// File : voice.h +// Creation date : Thu Aug 23 04:08:10 2001 GMT by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#include "kvi_window.h" + +#include "kvi_databuffer.h" +#include "kvi_sockettype.h" + +#include "codec.h" +#include "descriptor.h" +#include "thread.h" +#include "window.h" + +#include "kvi_tal_hbox.h" +#include <qlabel.h> +#include <qtoolbutton.h> +#include <qtimer.h> + +#ifndef _DCC_VOICE_CPP_ + extern bool kvi_dcc_voice_is_valid_codec(const char * codecName); +#endif + +#define KVI_DCC_VOICE_THREAD_ACTION_START_RECORDING 0 +#define KVI_DCC_VOICE_THREAD_ACTION_STOP_RECORDING 1 +#define KVI_DCC_VOICE_THREAD_ACTION_START_PLAYING 2 +#define KVI_DCC_VOICE_THREAD_ACTION_STOP_PLAYING 3 + +typedef struct _KviDccVoiceThreadOptions +{ + bool bForceHalfDuplex; + int iPreBufferSize; + int iSampleRate; + KviStr szSoundDevice; + KviDccVoiceCodec * pCodec; +} KviDccVoiceThreadOptions; + +class KviDccVoiceThread : public KviDccThread +{ + friend class KviDccVoice; +public: + KviDccVoiceThread(KviWindow * wnd,kvi_socket_t fd,KviDccVoiceThreadOptions * opt); + ~KviDccVoiceThread(); +protected: +// bool m_bUseGsm; + KviDccVoiceThreadOptions * m_pOpt; + int m_soundFd; + int m_soundFdMode; + KviDataBuffer m_outFrameBuffer; + KviDataBuffer m_inFrameBuffer; + KviDataBuffer m_inSignalBuffer; + KviDataBuffer m_outSignalBuffer; + bool m_bPlaying; + bool m_bRecording; + bool m_bRecordingRequestPending; + bool m_bSoundcardChecked; + int m_iLastSignalBufferSize; + long m_iLastSignalBufferTime; +// unsigned int m_uSleepTime; + KviMutex * m_pInfoMutex; + // stuff protected by the mutex: + int m_iInputBufferSize; + int m_iOutputBufferSize; +protected: + bool checkSoundcard(); + bool openSoundcardWithDuplexOption(int openMode,int failMode); + bool openSoundcard(int mode); + bool openSoundcardForWriting(); + bool openSoundcardForReading(); + void closeSoundcard(); + bool readWriteStep(); + bool soundStep(); + void startRecording(); + void stopRecording(); + void startPlaying(); + void stopPlaying(); + virtual void run(); +}; + +class KviDccMarshal; +class QSlider; + +class KviDccVoice : public KviDccWindow +{ + Q_OBJECT +public: + KviDccVoice(KviFrame *pFrm,KviDccDescriptor * dcc,const char * name); + ~KviDccVoice(); +protected: + KviTalHBox * m_pHBox; + QSlider * m_pVolumeSlider; + QLabel * m_pInputLabel; + QLabel * m_pOutputLabel; + QLabel * m_pRecordingLabel; + QLabel * m_pPlayingLabel; + QToolButton * m_pTalkButton; + QTimer * m_pUpdateTimer; + QString m_szTarget; + KviDccVoiceThread * m_pSlaveThread; +protected: + virtual void focusInEvent(QFocusEvent *); + virtual const QString & target(); + virtual void fillCaptionBuffers(); + virtual QPixmap * myIconPtr(); + virtual void resizeEvent(QResizeEvent *e); + virtual QSize sizeHint() const; + virtual bool event(QEvent *e); + virtual void getBaseLogFileName(KviStr &buffer); + void startTalking(); + void stopTalking(); + void startConnection(); + int getMixerVolume(void) const; +protected slots: + void handleMarshalError(int err); + void connected(); + void updateInfo(); + void startOrStopTalking(bool bStart); + void setMixerVolume(int); + void connectionInProgress(); +// void stopTalking(); +}; + +#if 0 + + + +/* + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +CODEC DEFINITION + + Sample rate = samples/sec (ex. 8000) + Sample size = bits (ex. 16 bits) + Sample endianness = le/be + + Sample compressor = name + + <rate>:<bits>:<endianness>:<compressor> + + 8000:16:le:null + 8000:16:le:gsm + 8000:16:le:adpcm + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class KviVoiceParty +{ +public: + KviVoiceParty(const QString &szNick,const QString &szIp,unsigned short uPort); + ~KviVoiceParty(); +protected: + QString m_szIp; + unsigned short m_uPort; + QString m_szNick; + KviPointerList<KviVoiceParty> * m_pChildrenTree; +public: + const QString & ip(){ return m_szIp; }; + unsigned short port(){ return m_uPort; }; + const QString & nick(){ return m_szNick; }; + void addChild(KviVoiceParty * pChild); +}; + + +KviVoiceParty::KviVoiceParty(const QString &szNick,const QString &szIp,unsigned short uPort) +: m_szIp(szIp), m_uPort(uPort), m_szNick(szNick) +{ + m_pChildrenTree = 0; +} + +KviVoiceParty::~KviVoiceParty() +{ + if(m_pChildrenTree)delete m_pChildrenTree; +} + +void KviVoiceParty::addChild(KviVoiceParty * pChild) +{ + if(!m_pChildrenTree) + { + m_pChildrenTree = new KviPointerList<KviVoiceParty>; + m_pChildrenTree->setAutoDelete(true); + } + m_pChildrenTree->append(pChild); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class KviVoiceAudioEncoder +{ +public: + KviVoiceAudioEncoder(); + ~KviVoiceAudioEncoder(); +public: + +}; + +class KviVoiceAudioDecoder +{ +public: + KviVoiceAudioDecoder(); + ~KviVoiceAudioDecoder(); +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class KviVoiceLink +{ +public: + KviVoiceLink(KviVoiceParty * pRemoteParty); + ~KviVoiceLink(); +protected: + QString m_szId; + KviVoiceParty * m_pRemoteParty; + KviVoiceAudioEncoder * m_pAudioEncoder; + KviVoiceAudioDecoder * m_pAudioDecoder; +public: + const QStirng & id(){ return m_szId; }; + KviVoiceParty * remoteParty(){ return m_pRemoteParty; }; +}; + +KviVoiceLink::KviVoiceLink(KviVoiceParty * pRemoteParty) +{ + KviQString::sprintf("%Q:%u",&(pRemoteParty->nick()),pRemoteParty->port()); + m_pRemoteParty = pRemoteParty; + m_pAudioEncoder = 0; + m_pAudioDecoder = 0; +} + +KviVoiceLink::~KviVoiceLink() +{ + delete m_pRemoteParty; + if(m_pAudioEncoder)delete m_pAudioEncoder; + if(m_pAudioDecoder)delete m_pAudioDecoder; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class KviVoice_r8000s16eL_to_r8000s16eB_Transformer +{ + +} + +class KviVoice_r8000s16eB_to_r8000s16eL_Transformer +{ + +} + +class KviVoice_r11025s16eL_to_r11025s16eB_Transformer +{ + +} + +class KviVoice_r11025s16eB_to_r11025s16eL_Transformer +{ + +} + +class KviVoice_r11025s16eL_to_r8000s16eL_Transformer +{ + +} + +class KviVoice_r11025s16eL_to_r8000s16eB_Transformer +{ + +} + +class KviVoice_r11025s16eB_to_r8000s16eL_Transformer +{ + +} + +class KviVoice_r8000s16eL_to_r11025s16eL_Transformer +{ + +} + +class KviVoice_r8000s16eL_to_r11025s16eB_Transformer +{ + +} + +class KviVoice_r8000s16eB_to_r11025s16eL_Transformer +{ + +} + + + +class KviVoiceConference +{ +public: + KviVoiceConference(); + ~KviVoiceConference(); +public: + KviPointerList<KviVoiceLink> * m_pLinks; + KviPointerHashTable<QString,KviVoiceLink> * + SOCKET m_hUdpSocket; + QString m_szLastError; + + unsigned int m_uLocalAudioSampleRate; // samples/sec + unsigned int m_uLocalAudioSampleSize; // bits + unsigned int m_uLocalAudioEndianness; // 0 = le, 1 = be + +public: + void conferenceThread(); +protected: + void conferenceThreadMain(); + bool setupUdpSocket(); +}; + +KviVoiceConference::KviVoiceConference() +{ + m_pLinks = new KviPointerList<KviVoiceLink>; + m_pLinks->setAutoDelete(true); +} + +KviVoiceConference::~KviVoiceConference() +{ + delete m_pLinks; +} + +bool KviVoiceConference::setupUdpSocket() +{ + return true; +} + +void KviVoiceConference::shutdownUdpSocket() +{ +} + +void KviVoiceConference::conferenceThreadMain() +{ + for(;;) + { + readAndDecompressIncomingDataForEveryLink(); + + mixIncomingDataToASingleStream(); + playIncomingDataSingleStream(); + + readLocalAudioStream(); + + foreach(link) + { + mixLocalAndOtherIncomingDataStreams() + compressAndSendOtherIncomingDataStreams() + } + + } +} + +void KviVoiceConference::conferenceThread() +{ + if(!setupUdpSocket())return; + + conferenceThreadMain(); + + shutdownUdpSocket(); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +*/ + +// DCC VOICE NG proto + +// +// tcp control connection +// --> HELLO: DccVoice protocol header +// <-- HELLO: DccVoice protocol header +// --> IACCEPT: Codec-description|CodecId,Codec-description|CodecID,Codec... (in order of preference) +// <-- IACCEPT: Codec-description|CodecID,Codec-description|CodecId,Codec... (in order of preference) +// --> MYADDRESS +// <-- MYADDRESS +// --> YOURIDIS: <local id for the remote end> (CID) +// <-- YOURIDIS: <local id for the remote end> (CID) + +// Audio is sent in blocks broken in chunks broken in udp packets +// Each block is a set of consecutive audio chunks that theoretically +// should be played consecutively. +// Each packet in a chunk has an ordinal +// Chunks must be relatively short in order +// to allow a remote end that looses a packet to +// synchronize after a short period of time +// The maximum number of packets in a chunk is 65535 (but a chunk should be no more than 24-32 KBytes in size +// and in general they should be as small as possible, even one packet per chunk, if the codec allows it) +// Each chunk should be encoded independently of the others +// We can switch codec at each chunk (but not at each packet) +// When some packets are lost we loose the entire chunk +// A block is completly synchronized in time (unless we loose some chunks: in that case +// we may decide to synchronize with silence or insert a glitch...) +// Decoding never depends on the future + +// Each packet should be decompressable (eventually dependently on the previous in the chunk) +// but playable independently + +// start UDP stream + +// UDP Packet format: + +// <magic byte>: byte +// <magic byte>: byte +// <local id>: word +// <payload len>: word +// <payload> + + +// Payload format: + +// <codec id>: word +// <ordinal in a chunk>: word (0 = beginning of a chunk) + +// read raw audio data at sample rate X, sample size Y +// multiplex data always at this sample rate and sample size + + +#endif + +#endif //_VOICE_H_ |