Hey all,
currently I have a problem in my audio-player project with the float sample type. Other sample types like QAudioFormat::SignedInt and QAudioFormat::UnSignedInt work as expected. However, if I try to play audio streams with the sample type QAudioFormat::Float (e.g. pcm_f32le), I just hear noise. Here's what I did for now:

MBuffer.cpp:
Qt Code:
  1. MBuffer::MBuffer(AVFormatContext *formatContext, AVCodecContext *codecCtx, int audio_stream, QObject *parent):
  2. QBuffer(parent),formatContext(formatContext), codecContext(codecCtx), audioStream(audio_stream)
  3. {
  4. med_buffer = (uint8_t*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
  5.  
  6. buffer_offset = 0;
  7. pkt_size_remaining = 0;
  8. }
  9. qint64 MBuffer::readData(char *data, qint64 maxlen)
  10. {
  11. qint64 written = 0;
  12. AVPacket packet;
  13.  
  14. av_init_packet(&packet);
  15.  
  16. while( pkt_size_remaining == 0 )
  17. {
  18. int error;
  19. qDebug() << "pkt_size_remaining == 0 -> read new packet";
  20. if( (error = av_read_frame(formatContext, &packet)) != 0 )
  21. {
  22. qWarning() << "couldnt read packet AVERROR= " << error;
  23. return 0;
  24. }
  25. if( packet.stream_index == audioStream )
  26. {
  27. pkt_data_pointer = packet.data;
  28. pkt_size_remaining = packet.size;
  29. }
  30. }
  31.  
  32. while(pkt_size_remaining > 0)
  33. {
  34. int len, data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
  35.  
  36.  
  37. packet.data = pkt_data_pointer;
  38. packet.size = pkt_size_remaining;
  39.  
  40. //decode
  41. len = avcodec_decode_audio3(codecContext, (int16_t*)med_buffer, &data_size, &packet );
  42. if( len <= 0 )
  43. qWarning() << "no data read from packet";
  44. else
  45. {
  46. pkt_size_remaining -= len;
  47. pkt_data_pointer += len;
  48. }
  49. if( data_size > 0 )
  50. {
  51. memcpy((void*)data, (const void*)med_buffer, data_size );
  52. written = data_size;
  53. }
  54. qDebug() << "data_size= " << data_size << "\twritten= " << written;
  55. qDebug() << "maxlen= " << maxlen;
  56. }
  57. return written;
  58. }
To copy to clipboard, switch view to plain text mode 

DecodeThread.cpp:
Qt Code:
  1. void DecodeThread::openFile()
  2. {
  3. av_register_all();
  4.  
  5. audioStream = -1;
  6. AVCodec *codec;
  7.  
  8. if( av_open_input_file(&formatContext, WMV, NULL,0,NULL) != 0 )
  9. qWarning() << "couldnt open input file";
  10.  
  11. if( av_find_stream_info(formatContext) < 0 )
  12. qWarning() << "couldnt obtain stream info";
  13.  
  14. av_dump_format(formatContext, 0, WMV,0);
  15.  
  16. for( unsigned int i=0; i < formatContext->nb_streams; i++ )
  17. {
  18. if( formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
  19. {
  20. audioStream = i;
  21. break;
  22. }
  23. }
  24. if( audioStream == -1 )
  25. {
  26. qWarning() << "could not find audio stream";
  27. return;
  28. }
  29.  
  30. codecContext = formatContext->streams[audioStream]->codec;
  31.  
  32. codec = avcodec_find_decoder(codecContext->codec_id);
  33. if(!codec)
  34. qWarning() << "no codec found";
  35.  
  36. if( avcodec_open(codecContext,codec) < 0)
  37. qWarning() << "could not open codec";
  38. }
  39.  
  40. void DecodeThread::startAudio()
  41. {
  42. openFile();
  43.  
  44. MBuffer *buffer = new MBuffer(formatContext,codecContext, audioStream);
  45. if( !buffer->open(QBuffer::ReadOnly) )
  46. qDebug() << "couldnt open buffer";
  47.  
  48. // QAudioFormat format;
  49. // format.setFrequency(codecContext->sample_rate);
  50. // format.setChannels(2);
  51. // format.setSampleSize(16);
  52. // format.setCodec("audio/pcm");
  53. // format.setByteOrder(QAudioFormat::LittleEndian);
  54. // format.setSampleType(QAudioFormat::SignedInt);
  55.  
  56. QAudioFormat format;
  57. format.setFrequency(codecContext->sample_rate);
  58. format.setChannels(2);
  59. format.setSampleSize(32);
  60. format.setSampleType(QAudioFormat::Float);
  61. format.setByteOrder(QAudioFormat::LittleEndian);
  62. format.setCodec("audio/pcm");
  63.  
  64. if( !format.isValid() ) {
  65. qWarning() << "format is invalid!!";
  66. }
  67.  
  68. QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
  69.  
  70. // qDebug() << "Codecs= " << info.supportedCodecs();
  71. // qDebug() << "SampleTypes= " << info.supportedSampleTypes();
  72. // qDebug() << "Channels= " << info.supportedChannelCounts();
  73. // qDebug() << "ByteOrders= " << info.supportedByteOrders();
  74. // qDebug() << "Frequencies= " << info.supportedFrequencies();
  75.  
  76. if (!info.isFormatSupported(format)) {
  77. qWarning()<<"raw audio format not supported by backend, cannot play audio.";
  78. format = info.nearestFormat(format);
  79. }
  80.  
  81. if( !format.isValid() ) {
  82. qWarning() << "still not supported!";
  83. return;
  84. }
  85.  
  86. QAudioOutput *output = new QAudioOutput(format);
  87. output->start(buffer);
  88.  
  89. }
To copy to clipboard, switch view to plain text mode 

Thanks in advance,
Biberbaer