Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-42159

Unable to adjust audio input level on Android

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 5.4.1
    • 5.3.2
    • Multimedia
    • None
    • Desktop (Ubuntu 14.04. 64-bit, GCC 4.8.2)
      Android (Samsung Galaxy Tab2 10.1)
      Android NDK r10
    • Android
    • 9496d5fba5439bf4e4c1d80b5e5f76af82b89165

    Description

      I am not able to adjust the audio input volume on Android. Please find attached a minimal code example producing the following output:

      Desktop (Ubuntu 14.04. 64-bit)
      
      volume set:  0  volume returned:  0  bytes read:  31008  min value:  -2599  max value:  25615
      volume set:  0.1  volume returned:  0.1  bytes read:  20672  min value:  0  max value:  0
      volume set:  0.2  volume returned:  0.2  bytes read:  20672  min value:  -15485  max value:  7761
      volume set:  0.3  volume returned:  0.3  bytes read:  16646  min value:  -12864  max value:  11128
      volume set:  0.4  volume returned:  0.4  bytes read:  28778  min value:  -16597  max value:  23752
      volume set:  0.5  volume returned:  0.5  bytes read:  20672  min value:  -18153  max value:  32530
      volume set:  0.6  volume returned:  0.6  bytes read:  20672  min value:  -15869  max value:  32767
      volume set:  0.7  volume returned:  0.7  bytes read:  15856  min value:  -11264  max value:  30963
      volume set:  0.8  volume returned:  0.8  bytes read:  29174  min value:  -10181  max value:  32767
      volume set:  0.9  volume returned:  0.9  bytes read:  20672  min value:  -7711  max value:  32767
      volume set:  1  volume returned:  1  bytes read:  20672  min value:  -6484  max value:  32767
      
      
      Android (Samsung Galaxy Tab2 10.1)
      
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0  volume returned:  0  bytes read:  32768  min value:  -25488  max value:  27945
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0.1  volume returned:  0.1  bytes read:  32768  min value:  -26728  max value:  31593
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0.2  volume returned:  0.2  bytes read:  32768  min value:  -28400  max value:  27121
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0.3  volume returned:  0.3  bytes read:  32768  min value:  -27679  max value:  26496
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0.4  volume returned:  0.4  bytes read:  32768  min value:  -29840  max value:  30029
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0.5  volume returned:  0.5  bytes read:  32768  min value:  -26258  max value:  27485
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0.6  volume returned:  0.6  bytes read:  32768  min value:  -27754  max value:  29813
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0.7  volume returned:  0.7  bytes read:  32768  min value:  -26040  max value:  29565
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0.8  volume returned:  0.8  bytes read:  32768  min value:  -28947  max value:  29668
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  0.9  volume returned:  0.9  bytes read:  32768  min value:  -29395  max value:  32061
      D/Qt      ( 4385): ../MinimalQAudioInExample/myobject.cpp:66 (void MyObject::processAudio()): volume set:  1  volume returned:  1  bytes read:  32768  min value:  -28067  max value:  26618
      I/AndroidRuntime( 4385): VM exiting with result code 0, cleanup skipped.
      
      observations:
      
      desktop: volume 0.0, values != 0;
               volume 0.1, values == 0;
               values are increasing along with volume like expected;
      
      android: volume setting is accepted, but has no real effect;
               volume 0.0, values != 0;
               this contradicts the documentation, where not supported volume setting always returns 1.0;
      
      myobject.h
      #ifndef MYOBJECT_H
      #define MYOBJECT_H
      
      #include <QObject>
      #include <QAudioFormat>
      #include <QAudioInput>
      #include <QIODevice>
      
      class MyObject : public QObject
      {
          Q_OBJECT
      public:
          explicit MyObject(QObject *parent = 0);
          ~MyObject(void);
          int init(void);
      public slots:
          void processAudio(void);
      private:
          qreal _volume;
          QAudioFormat *_ptrAudioFormat;
          QAudioInput *_ptrAudioInput;
          QIODevice *_ptrInputDevice;
          int _bufferSize;
      };
      
      #endif // MYOBJECT_H
      
      myobject.cpp
      MyObject::MyObject(QObject *parent) :
          QObject(parent),
          _volume(0.0),
          _ptrAudioFormat(0),
          _ptrAudioInput(0),
          _ptrInputDevice(0),
          _bufferSize(32 * 1024)
      {
      }
      
      int MyObject::init()
      {
          _ptrAudioFormat = new QAudioFormat();
          _ptrAudioFormat->setChannelCount(1);
          _ptrAudioFormat->setSampleRate(16000);
          _ptrAudioFormat->setSampleSize(16);
          _ptrAudioFormat->setSampleType(QAudioFormat::SignedInt);
          _ptrAudioFormat->setByteOrder(QAudioFormat::LittleEndian);
          _ptrAudioFormat->setCodec("audio/pcm");
      
          _ptrAudioInput = new QAudioInput(*_ptrAudioFormat);
          _ptrAudioInput->setBufferSize(_bufferSize);
          _ptrAudioInput->setVolume(_volume);
          _ptrInputDevice = _ptrAudioInput->start();
      
          if (_ptrInputDevice == 0)
          {
              qDebug() << _ptrAudioInput->error();
              return -1;
          }
          else
          {
              connect(_ptrInputDevice, SIGNAL(readyRead()), this, SLOT(processAudio()));
          }
      
          return 0;
      }
      
      MyObject::~MyObject()
      {
          _ptrInputDevice = 0;
      
          if (_ptrAudioInput)
          {
              _ptrAudioInput->stop();
              delete _ptrAudioInput; _ptrAudioInput = 0;
          }
      
          if (_ptrAudioFormat)
          {
              delete _ptrAudioFormat; _ptrAudioFormat = 0;
          }
      }
      
      void MyObject::processAudio()
      {
              char *byteBuffer = new char[_bufferSize];
              short *sampleBuffer = new short[_bufferSize / sizeof(short)];
      
              _ptrAudioInput->setVolume(_volume);
      
              int bytesRead = static_cast<int>(_ptrInputDevice->read(byteBuffer, _bufferSize));
              memcpy(sampleBuffer, byteBuffer, bytesRead);
              int samplesRead = bytesRead / sizeof(short);
              int maxValue = 0; int minValue = 0;
              for (int s = 0; s < samplesRead; s ++)
              {
                  int value = static_cast<int>(sampleBuffer[s]);
                  if (minValue > value) { minValue = value; }
                  if (maxValue < value) { maxValue = value; }
              }
      
              qDebug() << "volume set: " << _volume
                       << " volume returned: " << _ptrAudioInput->volume()
                       << " bytes read: " << bytesRead
                       << " min value: " << minValue
                       << " max value: " << maxValue;
      
              delete [] sampleBuffer; sampleBuffer = 0;
              delete [] byteBuffer; byteBuffer = 0;
      
              if (_volume > 0.9)
              {
                  QApplication::exit(0);
              }
              else
              {
                  _volume += 0.1;
              }
      }
      
      main.cpp
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
          MyObject obj;
          int initValue = obj.init();
          if (initValue != 0)
          {
              return initValue;
          }
          return app.exec();
      }
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            ylopes Yoann Lopes
            wurzelpeter Markus Franke
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes