Que: How to play PCM data in Qt?



  • Explanation: I have character array and I want paly it by using Qt.
    I am using following code. But its playing something garbage voice.

    1. My_Audio.h
    #ifndef MYAUDIO
    #define MYAUDIO
    
    #endif // MYAUDIO
    
    
    #include <QDebug>
    #include <QIODevice>
    #include <QAudioInput>
    #include <QAudioOutput>
    #include <QCoreApplication>
    #include <QWidget>
    
    //#define SAMPLE_RATE 22050
    #define SAMPLE_RATE 22050
    #define CHANNELS 1
    #define SAMPLE_SIZE 16
    
    #define SAMPLE_TYPE SignedInt
    
    const float DurationSeconds = 0.1;
    const int ToneFrequencyHz = 4000;
    const int DataFrequencyHz = 44100;
    const int BufferSize   = 131072;
    
    class myAudio
    {
     // Q_OBJECT
    
    public:
        QAudioOutput *audioOut;
        QAudioInput  *audioIn;
        QWidget *parent;
    
    
        myAudio(QWidget *parent);
       ~myAudio(){}
       void fillBuffer();
        QAudioFormat formatIn,formatOut;
        QByteArray buff;
         QAudioDeviceInfo deviceinfo;
        QIODevice*            auIObuffer;     // IODevice to connect to m_AudioOutput
        signed short   aubuffer[BufferSize];     // Audio circular buffer
        int                      readpointer;           // Pointer to the portion of the audio buffer
                                                     // to be read.
        int                      writepointer;
    
    public slots:
        void write();
    };
    
    1. My_Audio.cpp
    #include "myAudio.h"
    #include <QDebug>
    #include <windows.h>
    #include <qmath.h>
    #include <qEndian.h>
    #include <QFile>
    
    myAudio::myAudio(QWidget *parent)
    {
       formatOut.setSampleRate(SAMPLE_RATE);
       formatOut.setChannelCount(CHANNELS);
       formatOut.setSampleSize(SAMPLE_SIZE);
       formatOut.setCodec("audio/pcm");
       formatOut.setByteOrder(QAudioFormat::LittleEndian);
       formatOut.setSampleType(QAudioFormat::SAMPLE_TYPE);
    
    //print out the output device setup parameters
    
       deviceinfo = QAudioDeviceInfo::defaultOutputDevice(); // Device info = default
    
       if(!deviceinfo.isFormatSupported(formatOut))
       {
           qDebug() << "\nformat specifieed not supported";
       }
    
          audioOut=0;
          audioOut = new QAudioOutput(deviceinfo, formatOut, parent);
          audioOut->setNotifyInterval(10);
          audioOut->setBufferSize(131072); //in bytes
          QObject::connect(audioOut, SIGNAL(notify()), parent, SLOT(write()));
       //auIObuffer->open(QIODevice::ReadOnly);
          auIObuffer = audioOut->start();
    
    
    //   print out the device specifications
        foreach(const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
            {
            qDebug() << "\nSuported output devices";
            qDebug() << "Device name: "             << deviceInfo.deviceName();
            qDebug() << "Supported channel count: "   << deviceInfo.supportedChannelCounts();
            qDebug() << "Supported Codec: "           << deviceInfo.supportedCodecs();
            qDebug() << "Supported byte order: "      << deviceInfo.supportedByteOrders();
            qDebug() << "Supported Sample Rate: "     << deviceInfo.supportedSampleRates();
            qDebug() << "Supported Sample Size: "     << deviceInfo.supportedSampleSizes();
            qDebug() << "Supported Sample Type: "     << deviceInfo.supportedSampleTypes();
            qDebug() << "Preferred Device settings:"  << deviceInfo.preferredFormat();
            }
    
         for (int sample=0; sample<BufferSize; sample++) {
              signed short value=0;
              if ((sample>20000) && (sample<20000+(DurationSeconds*DataFrequencyHz))){
                float time = (float) sample/DataFrequencyHz ;
                float x = qSin(2 * M_PI *ToneFrequencyHz* time);
                value = static_cast<signed short>(x * 32767);
              }
              aubuffer[sample] = value;
         }
         writepointer=0;
         readpointer=0;
         write();
    }
    
    void myAudio::write()
    {
       int emptyBytes = audioOut->bytesFree(); // Check how many empty bytes are in the device buffer
       int periodSize = audioOut->periodSize(); // Check the ideal chunk size, in bytes
       int chunks = emptyBytes/periodSize;
       char *data = "#Dis";	// referring to “This” 
           auIObuffer->write((const char*) data, periodSize);
    }
    
    1. MainWindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
       Q_OBJECT
    
    public:
       explicit MainWindow(QWidget *parent = 0);
       ~MainWindow();
    
    private slots:
       void on_pushButton_clicked();
    
    private:
       Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    1. MainWindow.cpp
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "myaudio.h"
    myAudio *m;
    MainWindow::MainWindow(QWidget *parent) :
       QMainWindow(parent),
       ui(new Ui::MainWindow)
    {
       ui->setupUi(this);
    
    m = new myAudio(parent);
    
    }
    
    MainWindow::~MainWindow()
    {
       delete ui;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
       m->write();
    }
    
    1. Main.cpp
    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
       QApplication a(argc, argv);
       MainWindow w;
       w.show();
    
       return a.exec();
    }
    
    1. ProjectName.Pro
    QT       += core gui
    QT += multimedia widgets
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = ProjectName
    TEMPLATE = app
    CONFIG   -= app_bundle
    
    SOURCES += main.cpp\
           mainwindow.cpp \
       myaudio.cpp
    
    HEADERS  += mainwindow.h \
       myaudio.h
    
    FORMS    += mainwindow.ui
    

    Please help me on this.



  • It worked.

    Was doing mistake by providing actually speech content to write buffer api.
    Instead of speech content, actual PCM data need to be given.
    And Thanks to @Chris Kawa for editing post to make it more readable


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.