2011-05-13 111 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; 
}