Qt--使用RtAudio进行录音以及播放

来源:互联网 发布:简单java游戏源代码 编辑:程序博客网 时间:2024/06/06 16:35

其实,本篇博客主要是介绍一下RtAudio,只是在qt中使用罢了!

什么是RtAudio?
RtAudio provides a common API for realtime audio input/output across Linux (native ALSA, Jack, and OSS), Macintosh OS X (CoreAudio and Jack), and Windows(DirectSound, ASIO and WASAPI) operating systems.

官方地址:
http://www.music.mcgill.ca/~gary/rtaudio/

github地址:
https://github.com/thestk/rtaudio

下载rtaudio:
最新版本 (22 February 2016): Version 4.1.2

官方文档应用例子:

#include "RtAudio.h"#include <iostream>#include <cstdlib>#include <cstring>int record( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,         double streamTime, RtAudioStreamStatus status, void *userData ){  if ( status )    std::cout << "Stream overflow detected!" << std::endl;  // Do something with the data in the "inputBuffer" buffer.  return 0;}int main(){  RtAudio adc;  if ( adc.getDeviceCount() < 1 ) {    std::cout << "\nNo audio devices found!\n";    exit( 0 );  }  RtAudio::StreamParameters parameters;  parameters.deviceId = adc.getDefaultInputDevice();  parameters.nChannels = 2;  parameters.firstChannel = 0;  unsigned int sampleRate = 44100;  unsigned int bufferFrames = 256; // 256 sample frames  try {    adc.openStream( NULL, &parameters, RTAUDIO_SINT16,                    sampleRate, &bufferFrames, &record );    adc.startStream();  }  catch ( RtAudioError& e ) {    e.printMessage();    exit( 0 );  }  char input;  std::cout << "\nRecording ... press <enter> to quit.\n";  std::cin.get( input );  try {    // Stop the stream    adc.stopStream();  }  catch (RtAudioError& e) {    e.printMessage();  }  if ( adc.isStreamOpen() ) adc.closeStream();  return 0;}

Qt中的应用

功能:
1左声道
2右声道
3双声道

封装一个类,叫ThreadRecord,在多线程中使用RrAudio,当然是继承QThread:

class ThreadRecord :public QThread{public:    ThreadRecord();    static int record(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *userData);    bool flag;    int type;//通过type进行判断是使用左声道、右声道、双声道protected:    void run();private:    RtAudio adc;    RtAudio::StreamParameters input;    RtAudio::StreamParameters output;};

实现threadrecord.cc:

int ThreadRecord::record(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *userData){    if (status)        cout << "Stream overflow detected!" << std::endl;    short* output = static_cast<short*>(outputBuffer);    short* input = static_cast<short*>(inputBuffer);    short n = nBufferFrames;    int i = *(static_cast<int*>(userData));    if(i == 2) {        for (i = 0; i < nBufferFrames; i += 1) {            output[i] = input[i];        }    } else {        for (; i < nBufferFrames; i += 2) {            output[i] = input[i];        }    }    return 0;}void ThreadRecord::run(){    //adc为成员变量:RtAudio adc_;    // adc_.getDeviceCount()获得音频设备数量    for(int i = 0 ; i < adc_.getDeviceCount() ; i++)    {        qDebug()<< i << adc_.getDeviceInfo(i).name.c_str();    }    if (adc_.getDeviceCount() < 1) {        cout << "\nNo audio devices found!\n";        exit( 0 );    }    //adc_.getDefaultInputDevice();获得默认输入设备    input.deviceId = adc_.getDefaultInputDevice();    input.nChannels = 2;    input.firstChannel = 0;    output.deviceId = adc_.getDefaultOutputDevice();    output.nChannels = 2;    output.firstChannel = 0;    unsigned int sampleRate = 44100;    unsigned int bufferFrames = 256;     try {        adc_.openStream(&output, &input, RTAUDIO_SINT16, sampleRate,                       &bufferFrames, &record, static_cast<void*>(&type),                       NULL, &ErrorCallback);        adc_.startStream();    }    catch (RtAudioError& e) {        e.printMessage();        exit(0);    }    while (flag);    try {        adc_.stopStream();    }    catch (RtAudioError& e) {        e.printMessage();    }    if (adc_.isStreamOpen())        adc_.closeStream();}

使用,为了节省篇幅,只写一个函数:
type=0 左声道
type=1 右声道
type=2 双声道

void Recording::onLeftSoundButtonClicked(){    if (thread_record.isRunning())        thread_record.exit(0);    thread_record.flag = true;    thread_record.type = 0;    thread_record.start();}
1 0