QAudioOutput & QAudioFormat::Float

Alles rund um die Programmierung mit Qt
Antworten
Biberbaer
Beiträge: 1
Registriert: 29. August 2011 19:29

QAudioOutput & QAudioFormat::Float

Beitrag von Biberbaer »

Hallo,
ich habe bei meinem Audio-Player Projekt derzeit ein Problem mit dem Sample Typen. Bei den Sample Typen QAudioFormat::SignedInt und QAudioFormat::UnSignedInt funktioniert das Abspielen einwandfrei. Wenn ich allerdings versuche Audio Streams im QAudioFormat::Float abzuspielen (also z.B. pcm_f32le), bekomme ich nur ein lautes Rauschen. Hattet ihr schonmal ein ähnliches Problem? Anbei ein Minimalbeispiel:

MBuffer.cpp:

Code: Alles auswählen

MBuffer::MBuffer(AVFormatContext *formatContext, AVCodecContext *codecCtx,  int audio_stream,  QObject *parent):
    QBuffer(parent),formatContext(formatContext), codecContext(codecCtx), audioStream(audio_stream)
{
    med_buffer  = (uint8_t*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

    buffer_offset       = 0;
    pkt_size_remaining  = 0;
}
qint64 MBuffer::readData(char *data, qint64 maxlen)
{
    qint64      written = 0;
    AVPacket    packet;

    av_init_packet(&packet);

    while( pkt_size_remaining == 0 )
    {
        int error;
        qDebug() << "pkt_size_remaining == 0 -> read new packet";
        if( (error = av_read_frame(formatContext, &packet)) != 0 )
        {
            qWarning() << "couldnt read packet AVERROR= " << error;
            return 0;
        }
        if( packet.stream_index == audioStream )
        {
            pkt_data_pointer    = packet.data;
            pkt_size_remaining  = packet.size;
        }
    }

    while(pkt_size_remaining > 0)
    {
        int len, data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;


        packet.data = pkt_data_pointer;
        packet.size = pkt_size_remaining;

        //decode
        len = avcodec_decode_audio3(codecContext, (int16_t*)med_buffer, &data_size, &packet );
        if( len <= 0 )
            qWarning() << "no data read from packet";
        else
        {
            pkt_size_remaining  -= len;
            pkt_data_pointer    += len;
        }
        if( data_size > 0 )
        {
            memcpy((void*)data, (const void*)med_buffer, data_size );
            written = data_size;
        }
        qDebug() << "data_size= " << data_size << "\twritten= " << written;
        qDebug() << "maxlen= " << maxlen;
    }
    return written;
}
DecodeThread.cpp:

Code: Alles auswählen

void DecodeThread::openFile()
{
    av_register_all();

    audioStream = -1;
    AVCodec *codec;

    if( av_open_input_file(&formatContext, WMV, NULL,0,NULL) != 0 )
        qWarning() << "couldnt open input file";

    if( av_find_stream_info(formatContext) < 0 )
        qWarning() << "couldnt obtain stream info";

    av_dump_format(formatContext, 0, WMV,0);

    for( unsigned int i=0; i < formatContext->nb_streams; i++ )
    {
        if( formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
        {
            audioStream = i;
            break;
        }
    }
    if( audioStream == -1 )
    {
        qWarning() << "could not find audio stream";
        return;
    }

    codecContext = formatContext->streams[audioStream]->codec;

    codec = avcodec_find_decoder(codecContext->codec_id);
    if(!codec)
        qWarning() << "no codec found";

    if( avcodec_open(codecContext,codec) < 0)
        qWarning() << "could not open codec";
}

void DecodeThread::startAudio()
{
    openFile();

    MBuffer *buffer = new MBuffer(formatContext,codecContext, audioStream);
    if( !buffer->open(QBuffer::ReadOnly) )
        qDebug() << "couldnt open buffer";

//    QAudioFormat format;
//    format.setFrequency(codecContext->sample_rate);
//    format.setChannels(2);
//    format.setSampleSize(16);
//    format.setCodec("audio/pcm");
//    format.setByteOrder(QAudioFormat::LittleEndian);
//    format.setSampleType(QAudioFormat::SignedInt);

    QAudioFormat format;
    format.setFrequency(codecContext->sample_rate);
    format.setChannels(2);
    format.setSampleSize(32);
    format.setSampleType(QAudioFormat::Float);
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setCodec("audio/pcm");

    if( !format.isValid() ) {
        qWarning() << "format is invalid!!";
    }

    QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());

//    qDebug() << "Codecs= " << info.supportedCodecs();
//    qDebug() << "SampleTypes= " << info.supportedSampleTypes();
//    qDebug() << "Channels= " << info.supportedChannelCounts();
//    qDebug() << "ByteOrders= " << info.supportedByteOrders();
//    qDebug() << "Frequencies= " << info.supportedFrequencies();

    if (!info.isFormatSupported(format)) {
        qWarning()<<"raw audio format not supported by backend, cannot play audio.";
        format = info.nearestFormat(format);
    }

    if( !format.isValid() ) {
        qWarning() << "still not supported!";
        return;
    }

    QAudioOutput *output = new QAudioOutput(format);
    output->start(buffer);

}
Antworten