2011-05-13 106 views
2

我試圖通過GSM調制解調器進行語音通話的功能,在qt上創建應用程序。現在我正在尋找能夠捕捉來自微型語音並能夠調節語音音量的圖書館。 Qt的聲子具有語音調節功能,但無法從麥克風捕捉數據。用於從音量調節麥克風獲取語音的Api

另一方面,有QtMultimedia,它可以捕獲這樣的數據,但無法調節音量。

是否有任何可以完成這兩項任務的C++庫,並且可以通過win | mac | linux進行移植?

回答

4

終於我用QtMultimedia +子類化QIODevice完成了。

在輸入和輸出我有pcm格式,有符號,所以我只是將輸入/輸出流的字節值乘以一些浮點值設置音量級別,之後我將數據寫入我需要的設備。

class VOICEIO_EXPORT VoiceIOAdapter : public QIODevice 
{ 
    Q_OBJECT 

public: 
    VoiceIOAdapter(QObject *parent,QIODevice* dev); 
    VoiceIOAdapter(QObject *parent); 
    ~VoiceIOAdapter(); 
    void setUnderlyingDevice(QIODevice* dev); 
    QIODevice* getUnderlyingDevice() const; 
     ... /*some qiodevice virtual functions reimplemented*/ 
     ... 
    float getOutVolume()const; 
    float getInVolume() const; 
public slots: 
    void setOutVolume(float); 
    void setInVolume(float); 
protected: 
    QIODevice* underlyingDevice; 
    virtual qint64 readData (char * data, qint64 maxSize); 
    virtual qint64 writeData (const char * data, qint64 maxSize); 
    void applyVolume(float value, QByteArray& input); 
    float outVolume;//1 
    float inVolume;//1 
}; 


void VoiceIOAdapter::applyVolume(float value, QByteArray& input) 
{ 
    Q_ASSERT(!(input.size()%2)); //SHORT,Signed,LE 
    qint16* data=reinterpret_cast<qint16*>(input.data()); 
    qint32 tmp; 
    for(int i=0;i<input.size()/2;i++) 
    { 
     tmp=qint32(float(data[i])*value); 
     if(tmp>std::numeric_limits<qint16>::max()) 
     { 
      tmp=std::numeric_limits<qint16>::max(); 
     } 
     else if (tmp<std::numeric_limits<qint16>::min()) 
     { 
      tmp=std::numeric_limits<qint16>::min(); 
     } 
     data[i]=tmp; 
    } 
} 

qint64 VoiceIOAdapter::readData (char * data, qint64 maxSize) 
{ 
    if(!underlyingDevice) 
    { 
     return -1; 
    } 
     QByteArray decoded(maxSize ,0); 
    qint64 result=underlyingDevice->read(decoded.data(),maxSize); 
    if(result>0) 
    { 
       decoded.resize(result); 
     applyVolume(inVolume,decoded); 
     memcpy(data,decoded.data(),decoded.size()); 
    } 
    return result; 
} 

qint64 VoiceIOAdapter::writeData (const char * data, qint64 maxSize) 
{ 
    if(!underlyingDevice) 
    { 
     return -1; 
    } 
    QByteArray encoded(data,maxSize); 
    applyVolume(outVolume,encoded); 
    qint64 result=underlyingDevice->write(encoded.data(),maxSize); 
    return result; 
}