void CachingReaderWorker::processChunkReadRequest(
        ChunkReadRequest* request,
        ReaderStatusUpdate* update) {
    //qDebug() << "Processing ChunkReadRequest for" << chunk_number;

    // Initialize the output parameter
    update->chunk = request->chunk;
    update->chunk->frameCount = 0;

    const int chunk_number = request->chunk->chunk_number;
    if (!m_pAudioSource || chunk_number < 0) {
        update->status = CHUNK_READ_INVALID;
        return;
    }

    const SINT chunkFrameIndex =
            frameForChunk(chunk_number);
    if (!m_pAudioSource->isValidFrameIndex(chunkFrameIndex)) {
        // Frame index out of range
        update->status = CHUNK_READ_INVALID;
        return;
    }

    const SINT seekFrameIndex =
            m_pAudioSource->seekSampleFrame(chunkFrameIndex);
    if (seekFrameIndex != chunkFrameIndex) {
        // Failed to seek to the requested index.
        // Corrupt file? -> Stop reading!
        qWarning() << "Failed to seek chunk position";
        update->status = CHUNK_READ_INVALID;
        return;
    }

    const SINT framesRemaining =
            m_pAudioSource->getFrameIndexMax() - seekFrameIndex;
    const SINT framesToRead =
            math_min(kFramesPerChunk, framesRemaining);
    if (0 >= framesToRead) {
        // No more data available for reading
        update->status = CHUNK_READ_EOF;
        return;
    }

    const SINT framesRead =
            m_pAudioSource->readSampleFramesStereo(
                    framesToRead, request->chunk->stereoSamples, kSamplesPerChunk);
    DEBUG_ASSERT(framesRead <= framesToRead);
    if (framesRead < framesToRead) {
        // Failed to read data! Corrupt file?
        qWarning() << "Failed to read chunk samples";
        update->status = CHUNK_READ_INVALID;
        return;
    }
    DEBUG_ASSERT(framesRead == framesToRead);

    update->status = CHUNK_READ_SUCCESS;
    update->chunk->frameCount = framesRead;
}
Beispiel #2
0
void CachingReaderWorker::processChunkReadRequest(
        ChunkReadRequest* request,
        ReaderStatusUpdate* update) {
    //qDebug() << "Processing ChunkReadRequest for" << chunk_number;

    // Initialize the output parameter
    update->chunk = request->chunk;
    update->chunk->frameCountRead = 0;
    update->chunk->frameCountTotal = 0;

    const int chunk_number = request->chunk->chunk_number;
    if (!m_pAudioSource || chunk_number < 0) {
        update->status = CHUNK_READ_INVALID;
        return;
    }

    const SINT chunkFrameIndex =
            frameForChunk(chunk_number);
    if (!m_pAudioSource->isValidFrameIndex(chunkFrameIndex)) {
        // Frame index out of range
        qWarning() << "Invalid chunk seek position"
                << chunkFrameIndex;
        update->status = CHUNK_READ_INVALID;
        return;
    }
    if (m_pAudioSource->getMaxFrameIndex() <= chunkFrameIndex) {
        // No more data available for reading
        update->status = CHUNK_READ_EOF;
        return;
    }

    const SINT seekFrameIndex =
            m_pAudioSource->seekSampleFrame(chunkFrameIndex);
    if (seekFrameIndex != chunkFrameIndex) {
        // Failed to seek to the requested index. The file might
        // be corrupt and decoding should be aborted.
        qWarning() << "Failed to seek chunk position"
                << seekFrameIndex << "<>" << chunkFrameIndex;
        update->status = CHUNK_READ_INVALID;
        return;
    }

    const SINT framesRemaining =
            m_pAudioSource->getMaxFrameIndex() - seekFrameIndex;
    const SINT framesToRead =
            math_min(kFramesPerChunk, framesRemaining);
    if (0 >= framesToRead) {
        // No more data available for reading
        update->status = CHUNK_READ_EOF;
        return;
    }

    const SINT framesRead =
            m_pAudioSource->readSampleFramesStereo(
                    framesToRead, request->chunk->stereoSamples, kSamplesPerChunk);
    DEBUG_ASSERT(framesRead <= framesToRead);
    update->chunk->frameCountRead = framesRead;
    update->chunk->frameCountTotal = framesToRead;
    if (framesRead < framesToRead) {
        // Incomplete read! Corrupt file?
        qWarning() << "Incomplete chunk read @" << seekFrameIndex
                << "[" << m_pAudioSource->getMinFrameIndex()
                << "," << m_pAudioSource->getFrameCount()
                << "]:" << framesRead << "<" << framesToRead;
        SampleUtil::clear(
                request->chunk->stereoSamples + (framesRead * kChunkChannels),
                (framesToRead - framesRead) * kChunkChannels);
        update->status = CHUNK_READ_PARTIAL;
    } else {
        update->status = CHUNK_READ_SUCCESS;
    }
}