Пример #1
0
std::pair<TweakableState, bool> TweakableParser<bool>::parse(Containers::ArrayView<const char> value) {
    if(value.size() == 4 && std::strncmp(value.data(), "true", value.size()) == 0)
        return {TweakableState::Success, true};
    if(value.size() == 5 && std::strncmp(value.data(), "false", value.size()) == 0)
        return {TweakableState::Success, false};

    Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not a boolean literal";
    return {TweakableState::Recompile, {}};
}
Пример #2
0
bool Directory::write(const std::string& filename, const Containers::ArrayView<const void> data) {
    std::ofstream file(filename, std::ofstream::binary);
    if(!file) return false;

    file.write(reinterpret_cast<const char*>(data.data()), data.size());
    return true;
}
Пример #3
0
template<UnsignedInt dimensions> void BufferImage<dimensions>::setData(const PixelStorage storage, const PixelFormat format, const PixelType type, const VectorTypeFor<dimensions, Int>& size, Containers::ArrayView<const void> const data, const BufferUsage usage) {
    _storage = storage;
    _format = format;
    _type = type;
    _size = size;

    /* Keep the old storage if zero-sized nullptr buffer was passed */
    if(data.data() == nullptr && data.size() == 0)
        CORRADE_ASSERT(Implementation::imageDataSize(*this) <= _dataSize, "BufferImage::setData(): bad current storage size, got" << _dataSize << "but expected at least" << Implementation::imageDataSize(*this), );
    else {
Пример #4
0
void StbVorbisImporter::doOpenData(Containers::ArrayView<const char> data) {

    Int numChannels, frequency;
    Short* decodedData = nullptr;

    Int samples = stb_vorbis_decode_memory(reinterpret_cast<const UnsignedByte*>(data.data()), data.size(), &numChannels, &frequency, &decodedData);

    if(samples == -1) {
        Error() << "Audio::StbVorbisImporter::openData(): the file signature is invalid";
        return;
    } else if (samples == -2) {
        /* memory allocation failure */
        Error() << "Audio::StbVorbisImporter::openData(): out of memory";
        return;
    }

    Containers::Array<char> tempData{reinterpret_cast<char*>(decodedData), size_t(samples*numChannels*2),
        [](char* data, size_t) { std::free(data); }};
    _frequency = frequency;

    /* Decide about format */
    if(numChannels == 1)
        _format = Buffer::Format::Mono16;
    else if(numChannels == 2)
        _format = Buffer::Format::Stereo16;
    /** @todo Buffer::Format::*Float32 when extension support is done */
    else {
        Error() << "Audio::StbVorbisImporter::openData(): unsupported channel count"
                << numChannels << "with" << 16 << "bits per sample";
        return;
    }

    _data = std::move(tempData);

    return;
}
Пример #5
0
void DrWavImporter::doOpenData(const Containers::ArrayView<const char> data) {
    drwav* const handle = drwav_open_memory(data.data(), data.size());
    if(!handle) {
        Error() << "Audio::DrWavImporter::openData(): failed to open and decode WAV data";
        return;
    }
    Containers::ScopeGuard drwavClose{handle, drwav_close};

    const std::uint64_t samples = handle->totalSampleCount;
    const std::uint32_t frequency = handle->sampleRate;
    const std::uint8_t numChannels = handle->channels;
    const std::uint8_t bitsPerSample = handle->bitsPerSample;

    /* If the bits per sample is exact, we can read data raw */
    const Int notExactBitsPerSample = ((bitsPerSample % 8) ? 1 : 0);

    /* Normalize bit amounts to multiples of 8, rounding up */
    const UnsignedInt normalizedBytesPerSample = (bitsPerSample / 8) + notExactBitsPerSample;

    if(numChannels == 0 || numChannels == 3 || numChannels == 5 || numChannels > 8 ||
       normalizedBytesPerSample == 0 || normalizedBytesPerSample > 8) {
        Error() << "Audio::DrWavImporter::openData(): unsupported channel count"
                << numChannels << "with" << bitsPerSample
                << "bits per sample";
        return;
    }

    /* Can't load something with no samples */
    if(samples == 0) {
        Error() << "Audio::DrWavImporter::openData(): no samples";
        return;
    }

    _frequency = frequency;

    /* PCM has a lot of special cases, as we can read many formats directly */
    if(handle->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
        _format = PcmFormatTable[numChannels-1][normalizedBytesPerSample-1];
        CORRADE_INTERNAL_ASSERT(_format != BufferFormat{});

        /* If the data is exactly 8 or 16 bits, we can read it raw */
        if(!notExactBitsPerSample && normalizedBytesPerSample < 3) {
            _data = readRaw(handle, samples, normalizedBytesPerSample);
            return;

        /* If the data is approximately 24 bits or has many channels, a float is more than enough */
        } else if(normalizedBytesPerSample == 3 || (normalizedBytesPerSample > 3 && numChannels > 3)) {
            _data = read32fPcm(handle, samples, numChannels, _format);
            return;

        /* If the data is close to 8 or 16 bits, we can convert it from 32-bit PCM */
        } else if(normalizedBytesPerSample == 1 || normalizedBytesPerSample == 2) {
            Containers::Array<char> tempData(samples*sizeof(Int));
            drwav_read_s32(handle, samples, reinterpret_cast<Int*>(tempData.begin()));

            /* 32-bit PCM can be sliced down to 8 or 16 for direct reading */
            _data = convert32Pcm(tempData, samples, normalizedBytesPerSample);

            /* Convert 8 bit data to unsigned */
            if(normalizedBytesPerSample == 1)
                for(char& item: _data) item = item - 128;
            return;
        }

        /** @todo Allow loading of 32/64 bit streams to Double format to preserve all information */

    /* ALaw of 8/16 bits with 1/2 channels can be loaded directly */
    } else if(handle->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
        if(numChannels < 3 && !notExactBitsPerSample && (bitsPerSample == 8 || bitsPerSample == 16) ) {
            _format = ALawFormatTable[numChannels-1][normalizedBytesPerSample-1];
            _data = readRaw(handle, samples, normalizedBytesPerSample);
            return;
        }

    /* MuLaw of 8/16 bits with 1/2 channels can be loaded directly */
    } else if(handle->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
        if(numChannels < 3 && !notExactBitsPerSample && (bitsPerSample == 8 || bitsPerSample == 16) ) {
            _format = MuLawFormatTable[numChannels-1][normalizedBytesPerSample-1];
            _data = readRaw(handle, samples, normalizedBytesPerSample);
            return;
        }

    /* IEEE float or double can be loaded directly */
    } else if(handle->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
        if(!notExactBitsPerSample && (bitsPerSample == 32 || bitsPerSample == 64)) {
            _format = IeeeFormatTable[numChannels-1][(normalizedBytesPerSample / 4)-1];
            _data = readRaw(handle, samples, normalizedBytesPerSample);
            return;
        }
    }

    /* If we don't know what the format is, read it out as 32 bit float for compatibility */
    _data = read32fPcm(handle, samples, numChannels, _format);
    return;
}
Пример #6
0
void DrFlacImporter::doOpenData(Containers::ArrayView<const char> data) {
    drflac* const handle = drflac_open_memory(data.data(), data.size());
    if(!handle) {
        Error() << "Audio::DrFlacImporter::openData(): failed to open and decode FLAC data";
        return;
    }
    Containers::ScopeGuard drflacClose{handle, drflac_close};

    const std::uint64_t samples = handle->totalSampleCount;
    const std::uint8_t numChannels = handle->channels;
    const std::uint8_t bitsPerSample = handle->bitsPerSample;

    /* FLAC supports any bitspersample from 4 to 64, but DrFlac always gives us
       32-bit samples. So we normalize bit amounts to multiples of 8, rounding
       up. */
    const UnsignedInt normalizedBytesPerSample = (bitsPerSample + 7)/8;

    if(numChannels == 0 || numChannels == 3 || numChannels == 5 || numChannels > 8 ||
       normalizedBytesPerSample == 0 || normalizedBytesPerSample > 8) {
        Error() << "Audio::DrFlacImporter::openData(): unsupported channel count"
                << numChannels << "with" << bitsPerSample
                << "bits per sample";
        return;
    }

    /* Can't load something with no samples */
    if(samples == 0) {
        Error() << "Audio::DrFlacImporter::openData(): no samples";
        return;
    }

    _frequency = handle->sampleRate;
    _format = flacFormatTable[numChannels-1][normalizedBytesPerSample-1];
    CORRADE_INTERNAL_ASSERT(_format != BufferFormat{});

    /* 32-bit integers need to be normalized to Double (with a 32 bit mantissa) */
    if(normalizedBytesPerSample == 4) {
        Containers::Array<Int> tempData(samples);
        drflac_read_s32(handle, samples, reinterpret_cast<Int*>(tempData.begin()));

        /* If the channel is mono/stereo, we can use double samples */
        if(numChannels < 3) {
            Containers::Array<Double> doubleData(samples);

            for(std::size_t i = 0; i < samples; ++i) {
                doubleData[i] = Math::unpack<Double>(tempData[i]);
            }

            const char* doubleBegin = reinterpret_cast<const char*>(doubleData.begin());
            const char* doubleEnd = reinterpret_cast<const char*>(doubleData.end());

            _data = Containers::Array<char>(samples*sizeof(Double));
            std::copy(doubleBegin, doubleEnd, _data.begin());

        /* Otherwise, convert to float */
        } else {
            Containers::Array<Float> floatData(samples);

            for(std::size_t i = 0; i < samples; ++i) {
                floatData[i] = Math::unpack<Float>(tempData[i]);
            }

            const char* floatBegin = reinterpret_cast<const char*>(floatData.begin());
            const char* floatEnd = reinterpret_cast<const char*>(floatData.end());

            _data = Containers::Array<char>(samples*sizeof(Float));
            std::copy(floatBegin, floatEnd, _data.begin());
        }

        return;
    }

    Containers::Array<char> tempData(samples*sizeof(Int));
    drflac_read_s32(handle, samples, reinterpret_cast<Int*>(tempData.begin()));

    _data = convert32PCM(tempData, samples, normalizedBytesPerSample);

    /* 8-bit needs to become unsigned */
    if(normalizedBytesPerSample == 1) {
        for(char& item: _data) item = item - 128;

    /* 24-bit needs to become float */
    } else if(normalizedBytesPerSample == 3) {
        Containers::Array<Float> floatData(samples);

        for(std::size_t i = 0; i != samples; ++i) {
            const UnsignedInt s0 = _data[i*3 + 0];
            const UnsignedInt s1 = _data[i*3 + 1];
            const UnsignedInt s2 = _data[i*3 + 2];

            const Int intData = Int((s0 << 8) | (s1 << 16) | (s2 << 24));
            floatData[i] = Math::unpack<Float>(intData);
        }

        const char* const floatBegin = reinterpret_cast<const char*>(floatData.begin());
        const char* const floatEnd = reinterpret_cast<const char*>(floatData.end());

        _data = Containers::Array<char>(samples*sizeof(Float));
        std::copy(floatBegin, floatEnd, _data.begin());
    }

    return;
}