/* * QtSpeex - Speex bindings for Qt * Copyright (C) 2010 Peter Zotov */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #define SAMPLING_RATE 16000 //must be the same as the speex setted mode (speex_wb_mode) #define FRAME_SIZE 320 //must be the same as the speex setted mode (speex_wb_mode) #define ECHOTAILSIZE 10 class SpeexBits; /** Speex jitter-buffer state. Never use it directly! */ typedef struct SpeexJitter { SpeexBits *current_packet; /**< Current Speex packet */ int valid_bits; /**< True if Speex bits are valid */ JitterBuffer *packets; /**< Generic jitter buffer state */ void *dec; /**< Pointer to Speex decoder */ spx_int32_t frame_size; /**< Frame size of Speex decoder */ int mostUpdatedTSatPut; /**< timestamp of the last packet put */ bool firsttimecalling_get; } SpeexJitter; namespace QtSpeex { class SpeexInputProcessor : public QIODevice { Q_OBJECT public: float dPeakSpeaker, dPeakSignal, dMaxMic, dPeakMic, dPeakCleanMic, dVoiceAcivityLevel; float fSpeechProb; SpeexInputProcessor(QObject* parent = 0); virtual ~SpeexInputProcessor(); bool hasPendingPackets(); QByteArray getNetworkPacket(); int iMaxBitRate; int iRealTimeBitrate; bool bPreviousVoice; public slots: void addEchoFrame(QByteArray*); signals: void networkPacketReady(); protected: virtual qint64 readData(char * /*data*/, qint64 /*maxSize*/) {return false;} //not used for input processor virtual qint64 writeData(const char *data, qint64 maxSize); virtual bool isSequential() const; private: QByteArray* lastEchoFrame; int iSilentFrames; int iHoldFrames; QMutex qmSpeex; void* enc_state; SpeexBits* enc_bits; int send_timestamp; //set at the encode time for the jitter buffer of the reciever bool bResetProcessor; SpeexPreprocessState* preprocessor; SpeexEchoState *echo_state; short * psClean; //temp buffer for audio sampling after echo cleaning (if enabled) QByteArray inputBuffer; QList outputNetworkBuffer; }; class SpeexOutputProcessor : public QIODevice { Q_OBJECT public: SpeexOutputProcessor(QObject* parent = 0); virtual ~SpeexOutputProcessor(); void putNetworkPacket(QString name, QByteArray packet); protected: virtual qint64 readData(char *data, qint64 maxSize); virtual qint64 writeData(const char * /*data*/, qint64 /*maxSize*/) {return 0;} //not used for output processor virtual bool isSequential() const; signals: void playingFrame(QByteArray*); private: QByteArray outputBuffer; QList inputNetworkBuffer; QHash userJitterHash; //SpeexJitter jitter; void speex_jitter_init(SpeexJitter *jit, void *decoder, int sampling_rate); void speex_jitter_destroy(SpeexJitter jitter); void speex_jitter_put(SpeexJitter jitter, char *packet, int len, int timestamp); void speex_jitter_get(SpeexJitter jitter, spx_int16_t *out, int *current_timestamp); int speex_jitter_get_pointer_timestamp(SpeexJitter jitter); }; }