【问题标题】:Api for capturing voice from microphone with volume regulation用于通过音量调节从麦克风捕获声音的 API
【发布时间】:2011-07-06 21:09:35
【问题描述】:

我试图在 qt 上创建能够通过 GSM 调制解调器进行语音呼叫的应用程序。现在我正在寻找可以从微型捕获语音并能够调节语音音量的库。 Qt 的声子具有语音调节功能,但不具备从麦克风捕获数据的能力。

另一方面,还有QtMultimedia,它可以捕获这样的数据,但不能调节音量。

是否有任何用于 c++ 的库可以完成这两项任务,并且可以通过 win|mac|linux 移植?

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    最后我用 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      相关资源
      最近更新 更多