various: moved more to core lib
This commit is contained in:
+16
-16
@@ -73,7 +73,7 @@ int InputCallback(const void *input, void *output, unsigned long frameCount, con
|
|||||||
FFmpegEncoder *f = static_cast<FFmpegEncoder*>(userData);
|
FFmpegEncoder *f = static_cast<FFmpegEncoder*>(userData);
|
||||||
|
|
||||||
AudioParams our_params = f->params().audio_params();
|
AudioParams our_params = f->params().audio_params();
|
||||||
our_params.set_format(AudioParams::GetPackedEquivalent(f->params().audio_params().format()));
|
our_params.set_format(f->params().audio_params().format().to_packed_equivalent());
|
||||||
|
|
||||||
f->WriteAudioData(our_params, reinterpret_cast<const uint8_t**>(&input), frameCount);
|
f->WriteAudioData(our_params, reinterpret_cast<const uint8_t**>(&input), frameCount);
|
||||||
|
|
||||||
@@ -119,27 +119,27 @@ void AudioManager::ClearBufferedOutput()
|
|||||||
output_buffer_->clear();
|
output_buffer_->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
PaSampleFormat AudioManager::GetPortAudioSampleFormat(AudioParams::Format fmt)
|
PaSampleFormat AudioManager::GetPortAudioSampleFormat(SampleFormat fmt)
|
||||||
{
|
{
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case AudioParams::kFormatUnsigned8Packed:
|
case SampleFormat::U8:
|
||||||
case AudioParams::kFormatUnsigned8Planar:
|
case SampleFormat::U8P:
|
||||||
return paUInt8;
|
return paUInt8;
|
||||||
case AudioParams::kFormatSigned16Packed:
|
case SampleFormat::S16:
|
||||||
case AudioParams::kFormatSigned16Planar:
|
case SampleFormat::S16P:
|
||||||
return paInt16;
|
return paInt16;
|
||||||
case AudioParams::kFormatSigned32Packed:
|
case SampleFormat::S32:
|
||||||
case AudioParams::kFormatSigned32Planar:
|
case SampleFormat::S32P:
|
||||||
return paInt32;
|
return paInt32;
|
||||||
case AudioParams::kFormatFloat32Packed:
|
case SampleFormat::F32:
|
||||||
case AudioParams::kFormatFloat32Planar:
|
case SampleFormat::F32P:
|
||||||
return paFloat32;
|
return paFloat32;
|
||||||
case AudioParams::kFormatSigned64Packed:
|
case SampleFormat::S64:
|
||||||
case AudioParams::kFormatSigned64Planar:
|
case SampleFormat::S64P:
|
||||||
case AudioParams::kFormatFloat64Packed:
|
case SampleFormat::F64:
|
||||||
case AudioParams::kFormatFloat64Planar:
|
case SampleFormat::F64P:
|
||||||
case AudioParams::kFormatInvalid:
|
case SampleFormat::INVALID:
|
||||||
case AudioParams::kFormatCount:
|
case SampleFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
#include "audio/audioprocessor.h"
|
#include "audio/audioprocessor.h"
|
||||||
#include "common/define.h"
|
#include "common/define.h"
|
||||||
#include "codec/ffmpeg/ffmpegencoder.h"
|
#include "codec/ffmpeg/ffmpegencoder.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/audioplaybackcache.h"
|
#include "render/audioplaybackcache.h"
|
||||||
#include "render/previewaudiodevice.h"
|
#include "render/previewaudiodevice.h"
|
||||||
|
|
||||||
@@ -94,7 +93,7 @@ private:
|
|||||||
|
|
||||||
virtual ~AudioManager() override;
|
virtual ~AudioManager() override;
|
||||||
|
|
||||||
static PaSampleFormat GetPortAudioSampleFormat(AudioParams::Format fmt);
|
static PaSampleFormat GetPortAudioSampleFormat(SampleFormat fmt);
|
||||||
|
|
||||||
void CloseOutputStream();
|
void CloseOutputStream();
|
||||||
|
|
||||||
|
|||||||
@@ -90,13 +90,13 @@ bool AudioProcessor::Open(const AudioParams &from, const AudioParams &to, double
|
|||||||
double speed_log = log(tempo) / log(base);
|
double speed_log = log(tempo) / log(base);
|
||||||
|
|
||||||
// This is the number of how many 0.5 or 2.0 tempos we need to daisychain
|
// This is the number of how many 0.5 or 2.0 tempos we need to daisychain
|
||||||
int whole = qFloor(speed_log);
|
int whole = std::floor(speed_log);
|
||||||
|
|
||||||
// Set speed_log to the remainder
|
// Set speed_log to the remainder
|
||||||
speed_log -= whole;
|
speed_log -= whole;
|
||||||
|
|
||||||
for (int i=0;i<=whole;i++) {
|
for (int i=0;i<=whole;i++) {
|
||||||
double filter_tempo = (i == whole) ? qPow(base, speed_log) : base;
|
double filter_tempo = (i == whole) ? std::pow(base, speed_log) : base;
|
||||||
|
|
||||||
if (qFuzzyCompare(filter_tempo, 1.0)) {
|
if (qFuzzyCompare(filter_tempo, 1.0)) {
|
||||||
// This filter would do nothing
|
// This filter would do nothing
|
||||||
@@ -117,7 +117,7 @@ bool AudioProcessor::Open(const AudioParams &from, const AudioParams &to, double
|
|||||||
|
|
||||||
// Create conversion filter
|
// Create conversion filter
|
||||||
if (from.sample_rate() != to.sample_rate() || from.channel_layout() != to.channel_layout() || from.format() != to.format()
|
if (from.sample_rate() != to.sample_rate() || from.channel_layout() != to.channel_layout() || from.format() != to.format()
|
||||||
|| (to.FormatIsPlanar() && create_tempo)) { // Tempo processor automatically converts to packed,
|
|| (to.format().is_planar() && create_tempo)) { // Tempo processor automatically converts to packed,
|
||||||
// so if the desired output is planar, it'll need
|
// so if the desired output is planar, it'll need
|
||||||
// to be converted
|
// to be converted
|
||||||
snprintf(filter_args, 200, "sample_fmts=%s:sample_rates=%d:channel_layouts=0x%" PRIx64,
|
snprintf(filter_args, 200, "sample_fmts=%s:sample_rates=%d:channel_layouts=0x%" PRIx64,
|
||||||
@@ -238,7 +238,7 @@ int AudioProcessor::Convert(float **in, int nb_in_samples, AudioProcessor::Buffe
|
|||||||
if (output) {
|
if (output) {
|
||||||
int nb_channels = to_.channel_count();
|
int nb_channels = to_.channel_count();
|
||||||
|
|
||||||
if (to_.FormatIsPacked()) {
|
if (to_.format().is_packed()) {
|
||||||
nb_channels = 1;
|
nb_channels = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ int AudioProcessor::Convert(float **in, int nb_in_samples, AudioProcessor::Buffe
|
|||||||
}
|
}
|
||||||
|
|
||||||
int nb_bytes = out_frame_->nb_samples * to_.bytes_per_sample_per_channel();
|
int nb_bytes = out_frame_->nb_samples * to_.bytes_per_sample_per_channel();
|
||||||
if (to_.FormatIsPacked()) {
|
if (to_.format().is_packed()) {
|
||||||
nb_bytes *= to_.channel_count();
|
nb_bytes *= to_.channel_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,16 +22,19 @@
|
|||||||
#define AUDIOPROCESSOR_H
|
#define AUDIOPROCESSOR_H
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <olive/core/core.h>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <libavfilter/avfilter.h>
|
#include <libavfilter/avfilter.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "common/define.h"
|
#include "common/define.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
class AudioProcessor
|
class AudioProcessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
#include "common/cpuoptimize.h"
|
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
@@ -459,8 +458,8 @@ void AudioVisualWaveform::DrawWaveform(QPainter *painter, const QRect& rect, con
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
next_sample_index = qMin(arr.size(),
|
next_sample_index = std::min(arr.size(),
|
||||||
start_sample_index + qFloor(rate_dbl * static_cast<double>(i - rect.x() + 1) / scale) * samples.channel_count());
|
size_t(start_sample_index + std::floor(rate_dbl * static_cast<double>(i - rect.x() + 1) / scale) * samples.channel_count()));
|
||||||
|
|
||||||
if (summary_index != sample_index) {
|
if (summary_index != sample_index) {
|
||||||
summary = AudioVisualWaveform::ReSumSamples(&arr.at(sample_index),
|
summary = AudioVisualWaveform::ReSumSamples(&arr.at(sample_index),
|
||||||
@@ -480,7 +479,7 @@ size_t AudioVisualWaveform::time_to_samples(const rational &time, double sample_
|
|||||||
|
|
||||||
size_t AudioVisualWaveform::time_to_samples(const double &time, double sample_rate) const
|
size_t AudioVisualWaveform::time_to_samples(const double &time, double sample_rate) const
|
||||||
{
|
{
|
||||||
return qFloor(time * sample_rate) * channels_;
|
return std::floor(time * sample_rate) * channels_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<rational, AudioVisualWaveform::Sample>::const_iterator AudioVisualWaveform::GetMipmapForScale(double scale) const
|
std::map<rational, AudioVisualWaveform::Sample>::const_iterator AudioVisualWaveform::GetMipmapForScale(double scale) const
|
||||||
|
|||||||
@@ -21,13 +21,14 @@
|
|||||||
#ifndef SUMSAMPLES_H
|
#ifndef SUMSAMPLES_H
|
||||||
#define SUMSAMPLES_H
|
#define SUMSAMPLES_H
|
||||||
|
|
||||||
|
#include <olive/core/core.h>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include "codec/samplebuffer.h"
|
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A buffer of data used to store a visual representation of audio
|
* @brief A buffer of data used to store a visual representation of audio
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -33,7 +33,5 @@ set(OLIVE_SOURCES
|
|||||||
codec/frame.h
|
codec/frame.h
|
||||||
codec/planarfiledevice.cpp
|
codec/planarfiledevice.cpp
|
||||||
codec/planarfiledevice.h
|
codec/planarfiledevice.h
|
||||||
codec/samplebuffer.cpp
|
|
||||||
codec/samplebuffer.h
|
|
||||||
PARENT_SCOPE
|
PARENT_SCOPE
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ extern "C" {
|
|||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "codec/samplebuffer.h"
|
|
||||||
#include "node/block/block.h"
|
#include "node/block/block.h"
|
||||||
#include "node/project/footage/footagedescription.h"
|
#include "node/project/footage/footagedescription.h"
|
||||||
#include "render/cancelatom.h"
|
#include "render/cancelatom.h"
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ void EncodingParams::Save(QXmlStreamWriter *writer) const
|
|||||||
writer->writeTextElement(QStringLiteral("codec"), QString::number(audio_codec_));
|
writer->writeTextElement(QStringLiteral("codec"), QString::number(audio_codec_));
|
||||||
writer->writeTextElement(QStringLiteral("samplerate"), QString::number(audio_params_.sample_rate()));
|
writer->writeTextElement(QStringLiteral("samplerate"), QString::number(audio_params_.sample_rate()));
|
||||||
writer->writeTextElement(QStringLiteral("channellayout"), QString::number(audio_params_.channel_layout()));
|
writer->writeTextElement(QStringLiteral("channellayout"), QString::number(audio_params_.channel_layout()));
|
||||||
writer->writeTextElement(QStringLiteral("format"), QString::number(audio_params_.format()));
|
writer->writeTextElement(QStringLiteral("format"), QString::fromStdString(audio_params_.format().to_string()));
|
||||||
writer->writeTextElement(QStringLiteral("bitrate"), QString::number(audio_bit_rate_));
|
writer->writeTextElement(QStringLiteral("bitrate"), QString::number(audio_bit_rate_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,9 +337,9 @@ QStringList Encoder::GetPixelFormatsForCodec(ExportCodec::Codec c) const
|
|||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<AudioParams::Format> Encoder::GetSampleFormatsForCodec(ExportCodec::Codec c) const
|
std::vector<SampleFormat> Encoder::GetSampleFormatsForCodec(ExportCodec::Codec c) const
|
||||||
{
|
{
|
||||||
return std::vector<AudioParams::Format>();
|
return std::vector<SampleFormat>();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMatrix4x4 EncodingParams::GenerateMatrix(EncodingParams::VideoScalingMethod method,
|
QMatrix4x4 EncodingParams::GenerateMatrix(EncodingParams::VideoScalingMethod method,
|
||||||
@@ -471,7 +471,7 @@ bool EncodingParams::LoadV1(QXmlStreamReader *reader)
|
|||||||
} else if (reader->name() == QStringLiteral("channellayout")) {
|
} else if (reader->name() == QStringLiteral("channellayout")) {
|
||||||
audio_params_.set_channel_layout(reader->readElementText().toULongLong());
|
audio_params_.set_channel_layout(reader->readElementText().toULongLong());
|
||||||
} else if (reader->name() == QStringLiteral("format")) {
|
} else if (reader->name() == QStringLiteral("format")) {
|
||||||
audio_params_.set_format(static_cast<AudioParams::Format>(reader->readElementText().toInt()));
|
audio_params_.set_format(SampleFormat::from_string(reader->readElementText().toStdString()));
|
||||||
} else if (reader->name() == QStringLiteral("bitrate")) {
|
} else if (reader->name() == QStringLiteral("bitrate")) {
|
||||||
audio_bit_rate_ = reader->readElementText().toLongLong();
|
audio_bit_rate_ = reader->readElementText().toLongLong();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-3
@@ -29,9 +29,7 @@
|
|||||||
#include "codec/exportcodec.h"
|
#include "codec/exportcodec.h"
|
||||||
#include "codec/exportformat.h"
|
#include "codec/exportformat.h"
|
||||||
#include "codec/frame.h"
|
#include "codec/frame.h"
|
||||||
#include "codec/samplebuffer.h"
|
|
||||||
#include "node/block/subtitle/subtitle.h"
|
#include "node/block/subtitle/subtitle.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/colortransform.h"
|
#include "render/colortransform.h"
|
||||||
#include "render/subtitleparams.h"
|
#include "render/subtitleparams.h"
|
||||||
#include "render/videoparams.h"
|
#include "render/videoparams.h"
|
||||||
@@ -204,7 +202,7 @@ public:
|
|||||||
static Encoder *CreateFromParams(const EncodingParams ¶ms);
|
static Encoder *CreateFromParams(const EncodingParams ¶ms);
|
||||||
|
|
||||||
virtual QStringList GetPixelFormatsForCodec(ExportCodec::Codec c) const;
|
virtual QStringList GetPixelFormatsForCodec(ExportCodec::Codec c) const;
|
||||||
virtual std::vector<AudioParams::Format> GetSampleFormatsForCodec(ExportCodec::Codec c) const;
|
virtual std::vector<SampleFormat> GetSampleFormatsForCodec(ExportCodec::Codec c) const;
|
||||||
|
|
||||||
const EncodingParams& params() const;
|
const EncodingParams& params() const;
|
||||||
|
|
||||||
|
|||||||
@@ -218,9 +218,9 @@ QStringList ExportFormat::GetPixelFormatsForCodec(ExportFormat::Format f, Export
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<AudioParams::Format> ExportFormat::GetSampleFormatsForCodec(Format format, ExportCodec::Codec c)
|
std::vector<SampleFormat> ExportFormat::GetSampleFormatsForCodec(Format format, ExportCodec::Codec c)
|
||||||
{
|
{
|
||||||
std::vector<AudioParams::Format> f;
|
std::vector<SampleFormat> f;
|
||||||
Encoder *e = Encoder::CreateFromFormat(format, EncodingParams());
|
Encoder *e = Encoder::CreateFromFormat(format, EncodingParams());
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include "common/define.h"
|
#include "common/define.h"
|
||||||
#include "exportcodec.h"
|
#include "exportcodec.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
@@ -62,7 +61,7 @@ public:
|
|||||||
static QList<ExportCodec::Codec> GetSubtitleCodecs(ExportFormat::Format f);
|
static QList<ExportCodec::Codec> GetSubtitleCodecs(ExportFormat::Format f);
|
||||||
|
|
||||||
static QStringList GetPixelFormatsForCodec(Format f, ExportCodec::Codec c);
|
static QStringList GetPixelFormatsForCodec(Format f, ExportCodec::Codec c);
|
||||||
static std::vector<AudioParams::Format> GetSampleFormatsForCodec(Format f, ExportCodec::Codec c);
|
static std::vector<SampleFormat> GetSampleFormatsForCodec(Format f, ExportCodec::Codec c);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, CancelAtom *can
|
|||||||
stream.set_stream_index(i);
|
stream.set_stream_index(i);
|
||||||
stream.set_channel_layout(channel_layout);
|
stream.set_channel_layout(channel_layout);
|
||||||
stream.set_sample_rate(avstream->codecpar->sample_rate);
|
stream.set_sample_rate(avstream->codecpar->sample_rate);
|
||||||
stream.set_format(AudioParams::kInternalFormat);
|
stream.set_format(FFmpegUtils::GetNativeSampleFormat(static_cast<AVSampleFormat>(avstream->codecpar->format)));
|
||||||
stream.set_time_base(avstream->time_base);
|
stream.set_time_base(avstream->time_base);
|
||||||
stream.set_duration(avstream->duration);
|
stream.set_duration(avstream->duration);
|
||||||
desc.AddAudioStream(stream);
|
desc.AddAudioStream(stream);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ QStringList FFmpegEncoder::GetPixelFormatsForCodec(ExportCodec::Codec c) const
|
|||||||
{
|
{
|
||||||
QStringList pix_fmts;
|
QStringList pix_fmts;
|
||||||
|
|
||||||
const AVCodec* codec_info = GetEncoder(c, AudioParams::kFormatInvalid);
|
const AVCodec* codec_info = GetEncoder(c, SampleFormat::INVALID);
|
||||||
|
|
||||||
if (codec_info) {
|
if (codec_info) {
|
||||||
for (int i=0; codec_info->pix_fmts[i]!=-1; i++) {
|
for (int i=0; codec_info->pix_fmts[i]!=-1; i++) {
|
||||||
@@ -69,29 +69,29 @@ QStringList FFmpegEncoder::GetPixelFormatsForCodec(ExportCodec::Codec c) const
|
|||||||
return pix_fmts;
|
return pix_fmts;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<AudioParams::Format> FFmpegEncoder::GetSampleFormatsForCodec(ExportCodec::Codec c) const
|
std::vector<SampleFormat> FFmpegEncoder::GetSampleFormatsForCodec(ExportCodec::Codec c) const
|
||||||
{
|
{
|
||||||
std::vector<AudioParams::Format> f;
|
std::vector<SampleFormat> f;
|
||||||
|
|
||||||
if (c == ExportCodec::kCodecPCM) {
|
if (c == ExportCodec::kCodecPCM) {
|
||||||
// FFmpeg lists these as separate codecs so we need custom functionality here
|
// FFmpeg lists these as separate codecs so we need custom functionality here
|
||||||
// We list signed 16 first because ExportDialog will always use the first element by default
|
// We list signed 16 first because ExportDialog will always use the first element by default
|
||||||
// (because first element is the "default" in FFmpeg)
|
// (because first element is the "default" in tFFmpeg)
|
||||||
f = {
|
f = {
|
||||||
AudioParams::kFormatSigned16Packed,
|
SampleFormat::S16,
|
||||||
AudioParams::kFormatUnsigned8Packed,
|
SampleFormat::U8,
|
||||||
AudioParams::kFormatSigned32Packed,
|
SampleFormat::S32,
|
||||||
AudioParams::kFormatSigned64Packed,
|
SampleFormat::S64,
|
||||||
AudioParams::kFormatFloat32Packed,
|
SampleFormat::F32,
|
||||||
AudioParams::kFormatFloat64Packed
|
SampleFormat::F64
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const AVCodec* codec_info = GetEncoder(c, AudioParams::kFormatInvalid);
|
const AVCodec* codec_info = GetEncoder(c, SampleFormat::INVALID);
|
||||||
|
|
||||||
if (codec_info && codec_info->sample_fmts) {
|
if (codec_info && codec_info->sample_fmts) {
|
||||||
for (int i=0; codec_info->sample_fmts[i]!=-1; i++) {
|
for (int i=0; codec_info->sample_fmts[i]!=-1; i++) {
|
||||||
AudioParams::Format this_format = FFmpegUtils::GetNativeSampleFormat(static_cast<AVSampleFormat>(codec_info->sample_fmts[i]));
|
SampleFormat this_format = FFmpegUtils::GetNativeSampleFormat(static_cast<AVSampleFormat>(codec_info->sample_fmts[i]));
|
||||||
if (this_format != AudioParams::kFormatInvalid) {
|
if (this_format != SampleFormat::INVALID) {
|
||||||
f.push_back(this_format);
|
f.push_back(this_format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -881,7 +881,7 @@ bool FFmpegEncoder::InitializeResampleContext(const AudioParams &audio)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AVCodec *FFmpegEncoder::GetEncoder(ExportCodec::Codec c, AudioParams::Format aformat)
|
const AVCodec *FFmpegEncoder::GetEncoder(ExportCodec::Codec c, SampleFormat aformat)
|
||||||
{
|
{
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ExportCodec::kCodecH264:
|
case ExportCodec::kCodecH264:
|
||||||
@@ -912,26 +912,26 @@ const AVCodec *FFmpegEncoder::GetEncoder(ExportCodec::Codec c, AudioParams::Form
|
|||||||
return avcodec_find_encoder(AV_CODEC_ID_AAC);
|
return avcodec_find_encoder(AV_CODEC_ID_AAC);
|
||||||
case ExportCodec::kCodecPCM:
|
case ExportCodec::kCodecPCM:
|
||||||
switch (aformat) {
|
switch (aformat) {
|
||||||
case AudioParams::kFormatInvalid:
|
case SampleFormat::INVALID:
|
||||||
case AudioParams::kFormatCount:
|
case SampleFormat::COUNT:
|
||||||
case AudioParams::kFormatUnsigned8Planar:
|
case SampleFormat::U8P:
|
||||||
case AudioParams::kFormatSigned16Planar:
|
case SampleFormat::S16P:
|
||||||
case AudioParams::kFormatSigned32Planar:
|
case SampleFormat::S32P:
|
||||||
case AudioParams::kFormatSigned64Planar:
|
case SampleFormat::S64P:
|
||||||
case AudioParams::kFormatFloat32Planar:
|
case SampleFormat::F32P:
|
||||||
case AudioParams::kFormatFloat64Planar:
|
case SampleFormat::F64P:
|
||||||
break;
|
break;
|
||||||
case AudioParams::kFormatUnsigned8Packed:
|
case SampleFormat::U8:
|
||||||
return avcodec_find_encoder(AV_CODEC_ID_PCM_U8);
|
return avcodec_find_encoder(AV_CODEC_ID_PCM_U8);
|
||||||
case AudioParams::kFormatSigned16Packed:
|
case SampleFormat::S16:
|
||||||
return avcodec_find_encoder(AV_CODEC_ID_PCM_S16LE);
|
return avcodec_find_encoder(AV_CODEC_ID_PCM_S16LE);
|
||||||
case AudioParams::kFormatSigned32Packed:
|
case SampleFormat::S32:
|
||||||
return avcodec_find_encoder(AV_CODEC_ID_PCM_S32LE);
|
return avcodec_find_encoder(AV_CODEC_ID_PCM_S32LE);
|
||||||
case AudioParams::kFormatSigned64Packed:
|
case SampleFormat::S64:
|
||||||
return avcodec_find_encoder(AV_CODEC_ID_PCM_S64LE);
|
return avcodec_find_encoder(AV_CODEC_ID_PCM_S64LE);
|
||||||
case AudioParams::kFormatFloat32Packed:
|
case SampleFormat::F32:
|
||||||
return avcodec_find_encoder(AV_CODEC_ID_PCM_F32LE);
|
return avcodec_find_encoder(AV_CODEC_ID_PCM_F32LE);
|
||||||
case AudioParams::kFormatFloat64Packed:
|
case SampleFormat::F64:
|
||||||
return avcodec_find_encoder(AV_CODEC_ID_PCM_F64LE);
|
return avcodec_find_encoder(AV_CODEC_ID_PCM_F64LE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
|
|
||||||
virtual QStringList GetPixelFormatsForCodec(ExportCodec::Codec c) const override;
|
virtual QStringList GetPixelFormatsForCodec(ExportCodec::Codec c) const override;
|
||||||
|
|
||||||
virtual std::vector<AudioParams::Format> GetSampleFormatsForCodec(ExportCodec::Codec c) const override;
|
virtual std::vector<SampleFormat> GetSampleFormatsForCodec(ExportCodec::Codec c) const override;
|
||||||
|
|
||||||
virtual bool Open() override;
|
virtual bool Open() override;
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ private:
|
|||||||
|
|
||||||
bool InitializeResampleContext(const AudioParams &audio);
|
bool InitializeResampleContext(const AudioParams &audio);
|
||||||
|
|
||||||
static const AVCodec *GetEncoder(ExportCodec::Codec c, AudioParams::Format aformat);
|
static const AVCodec *GetEncoder(ExportCodec::Codec c, SampleFormat aformat);
|
||||||
|
|
||||||
AVFormatContext* fmt_ctx_;
|
AVFormatContext* fmt_ctx_;
|
||||||
|
|
||||||
|
|||||||
@@ -21,14 +21,14 @@
|
|||||||
#ifndef PLANARFILEDEVICE_H
|
#ifndef PLANARFILEDEVICE_H
|
||||||
#define PLANARFILEDEVICE_H
|
#define PLANARFILEDEVICE_H
|
||||||
|
|
||||||
|
#include <olive/core/core.h>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "codec/samplebuffer.h"
|
|
||||||
#include "common/define.h"
|
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
class PlanarFileDevice : public QObject
|
class PlanarFileDevice : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|||||||
@@ -1,255 +0,0 @@
|
|||||||
/***
|
|
||||||
|
|
||||||
Olive - Non-Linear Video Editor
|
|
||||||
Copyright (C) 2022 Olive Team
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "samplebuffer.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include "common/cpuoptimize.h"
|
|
||||||
|
|
||||||
namespace olive {
|
|
||||||
|
|
||||||
SampleBuffer::SampleBuffer() :
|
|
||||||
sample_count_per_channel_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SampleBuffer::SampleBuffer(const AudioParams &audio_params, const rational &length) :
|
|
||||||
audio_params_(audio_params)
|
|
||||||
{
|
|
||||||
sample_count_per_channel_ = audio_params_.time_to_samples(length);
|
|
||||||
allocate();
|
|
||||||
}
|
|
||||||
|
|
||||||
SampleBuffer::SampleBuffer(const AudioParams &audio_params, size_t samples_per_channel) :
|
|
||||||
audio_params_(audio_params),
|
|
||||||
sample_count_per_channel_(samples_per_channel)
|
|
||||||
{
|
|
||||||
allocate();
|
|
||||||
}
|
|
||||||
|
|
||||||
const AudioParams &SampleBuffer::audio_params() const
|
|
||||||
{
|
|
||||||
return audio_params_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::set_audio_params(const AudioParams ¶ms)
|
|
||||||
{
|
|
||||||
if (is_allocated()) {
|
|
||||||
qWarning() << "Tried to set parameters on allocated sample buffer";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
audio_params_ = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::set_sample_count(const size_t &sample_count)
|
|
||||||
{
|
|
||||||
if (is_allocated()) {
|
|
||||||
qWarning() << "Tried to set sample count on allocated sample buffer";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sample_count_per_channel_ = sample_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::allocate()
|
|
||||||
{
|
|
||||||
if (!audio_params_.is_valid()) {
|
|
||||||
qWarning() << "Tried to allocate sample buffer with invalid audio parameters";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sample_count_per_channel_) {
|
|
||||||
qWarning() << "Tried to allocate sample buffer with zero sample count";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_allocated()) {
|
|
||||||
qWarning() << "Tried to allocate already allocated sample buffer";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data_.resize(audio_params_.channel_count());
|
|
||||||
for (int i=0; i<audio_params_.channel_count(); i++) {
|
|
||||||
data_[i].resize(sample_count_per_channel_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::destroy()
|
|
||||||
{
|
|
||||||
data_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::reverse()
|
|
||||||
{
|
|
||||||
if (!is_allocated()) {
|
|
||||||
qWarning() << "Tried to reverse an unallocated sample buffer";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t half_nb_sample = sample_count_per_channel_ / 2;
|
|
||||||
|
|
||||||
for (size_t i=0;i<half_nb_sample;i++) {
|
|
||||||
size_t opposite_ind = sample_count_per_channel_ - i - 1;
|
|
||||||
|
|
||||||
for (int j=0;j<audio_params_.channel_count();j++) {
|
|
||||||
std::swap(data_[j][i], data_[j][opposite_ind]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::speed(double speed)
|
|
||||||
{
|
|
||||||
if (!is_allocated()) {
|
|
||||||
qWarning() << "Tried to speed an unallocated sample buffer";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sample_count_per_channel_ = qRound(static_cast<double>(sample_count_per_channel_) / speed);
|
|
||||||
|
|
||||||
std::vector< std::vector<float> > output_data;
|
|
||||||
|
|
||||||
output_data.resize(audio_params_.channel_count());
|
|
||||||
for (int i=0; i<audio_params_.channel_count(); i++) {
|
|
||||||
output_data[i].resize(sample_count_per_channel_);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i=0;i<sample_count_per_channel_;i++) {
|
|
||||||
size_t input_index = qFloor(static_cast<double>(i) * speed);
|
|
||||||
|
|
||||||
for (int j=0;j<audio_params_.channel_count();j++) {
|
|
||||||
output_data[j][i] = data_[j][input_index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data_ = output_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::transform_volume(float f)
|
|
||||||
{
|
|
||||||
for (int i=0;i<audio_params().channel_count();i++) {
|
|
||||||
transform_volume_for_channel(i, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::transform_volume_for_channel(int channel, float volume)
|
|
||||||
{
|
|
||||||
float *cdat = data_[channel].data();
|
|
||||||
size_t unopt_start = 0;
|
|
||||||
|
|
||||||
#if defined(Q_PROCESSOR_X86) || defined(Q_PROCESSOR_ARM)
|
|
||||||
__m128 mult = _mm_load1_ps(&volume);
|
|
||||||
unopt_start = (sample_count_per_channel_ / 4) * 4;
|
|
||||||
for (size_t j=0; j<unopt_start; j+=4) {
|
|
||||||
float *here = cdat + j;
|
|
||||||
__m128 samples = _mm_loadu_ps(here);
|
|
||||||
__m128 multiplied = _mm_mul_ps(samples, mult);
|
|
||||||
_mm_storeu_ps(here, multiplied);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (size_t j=unopt_start; j<sample_count_per_channel_; j++) {
|
|
||||||
cdat[j] *= volume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::transform_volume_for_sample(size_t sample_index, float volume)
|
|
||||||
{
|
|
||||||
for (int i=0;i<audio_params().channel_count();i++) {
|
|
||||||
transform_volume_for_sample_on_channel(sample_index, i, volume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::transform_volume_for_sample_on_channel(size_t sample_index, int channel, float volume)
|
|
||||||
{
|
|
||||||
data_[channel][sample_index] *= volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::clamp()
|
|
||||||
{
|
|
||||||
for (int i=0; i<channel_count(); i++) {
|
|
||||||
clamp_channel(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::silence()
|
|
||||||
{
|
|
||||||
silence(0, sample_count_per_channel_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::silence(size_t start_sample, size_t end_sample)
|
|
||||||
{
|
|
||||||
silence_bytes(start_sample * sizeof(float), end_sample * sizeof(float));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::silence_bytes(size_t start_byte, size_t end_byte)
|
|
||||||
{
|
|
||||||
if (!is_allocated()) {
|
|
||||||
qWarning() << "Tried to fill an unallocated sample buffer";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0;i<audio_params().channel_count();i++) {
|
|
||||||
memset(reinterpret_cast<char*>(data_[i].data()) + start_byte, 0, end_byte - start_byte);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::set(int channel, const float *data, size_t sample_offset, size_t sample_length)
|
|
||||||
{
|
|
||||||
if (!is_allocated()) {
|
|
||||||
qWarning() << "Tried to fill an unallocated sample buffer";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&data_[channel].data()[sample_offset], data, sizeof(float) * sample_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SampleBuffer::clamp_channel(int channel)
|
|
||||||
{
|
|
||||||
const float min = -1.0f;
|
|
||||||
const float max = 1.0f;
|
|
||||||
|
|
||||||
float *cdat = data_[channel].data();
|
|
||||||
size_t unopt_start = 0;
|
|
||||||
|
|
||||||
#if defined(Q_PROCESSOR_X86) || defined(Q_PROCESSOR_ARM)
|
|
||||||
__m128 min_sse = _mm_load1_ps(&min);
|
|
||||||
__m128 max_sse = _mm_load1_ps(&max);
|
|
||||||
|
|
||||||
unopt_start = (sample_count_per_channel_ / 4) * 4;
|
|
||||||
for (size_t j=0; j<unopt_start; j+=4) {
|
|
||||||
float *here = cdat + j;
|
|
||||||
__m128 samples = _mm_loadu_ps(here);
|
|
||||||
|
|
||||||
samples = _mm_max_ps(samples, min_sse);
|
|
||||||
samples = _mm_min_ps(samples, max_sse);
|
|
||||||
|
|
||||||
_mm_storeu_ps(here, samples);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (size_t sample=unopt_start; sample<sample_count(); sample++) {
|
|
||||||
float &s = data(channel)[sample];
|
|
||||||
s = std::clamp(s, min, max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
/***
|
|
||||||
|
|
||||||
Olive - Non-Linear Video Editor
|
|
||||||
Copyright (C) 2022 Olive Team
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef SAMPLEBUFFER_H
|
|
||||||
#define SAMPLEBUFFER_H
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "render/audioparams.h"
|
|
||||||
|
|
||||||
namespace olive {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A buffer of audio samples
|
|
||||||
*
|
|
||||||
* Audio samples in this structure are always stored in PLANAR (separated by channel). This is done to simplify audio
|
|
||||||
* rendering code. This replaces the old system of using QByteArrays (containing packed audio) and while SampleBuffer
|
|
||||||
* replaces many of those in the rendering/processing side of things, QByteArrays are currently still in use for
|
|
||||||
* playback, including reading to and from the cache.
|
|
||||||
*/
|
|
||||||
class SampleBuffer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SampleBuffer();
|
|
||||||
SampleBuffer(const AudioParams& audio_params, const rational& length);
|
|
||||||
SampleBuffer(const AudioParams& audio_params, size_t samples_per_channel);
|
|
||||||
|
|
||||||
const AudioParams& audio_params() const;
|
|
||||||
void set_audio_params(const AudioParams& params);
|
|
||||||
|
|
||||||
const size_t &sample_count() const { return sample_count_per_channel_; }
|
|
||||||
void set_sample_count(const size_t &sample_count);
|
|
||||||
void set_sample_count(const rational &length)
|
|
||||||
{
|
|
||||||
set_sample_count(audio_params_.time_to_samples(length));
|
|
||||||
}
|
|
||||||
|
|
||||||
float* data(int channel)
|
|
||||||
{
|
|
||||||
return data_[channel].data();
|
|
||||||
}
|
|
||||||
|
|
||||||
const float* data(int channel) const
|
|
||||||
{
|
|
||||||
return data_.at(channel).data();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<float *> to_raw_ptrs()
|
|
||||||
{
|
|
||||||
std::vector<float *> r(data_.size());
|
|
||||||
for (size_t i=0; i<r.size(); i++) {
|
|
||||||
r[i] = data_[i].data();
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int channel_count() const { return data_.size(); }
|
|
||||||
|
|
||||||
bool is_allocated() const { return !data_.empty(); }
|
|
||||||
void allocate();
|
|
||||||
void destroy();
|
|
||||||
|
|
||||||
void reverse();
|
|
||||||
void speed(double speed);
|
|
||||||
void transform_volume(float f);
|
|
||||||
void transform_volume_for_channel(int channel, float volume);
|
|
||||||
void transform_volume_for_sample(size_t sample_index, float volume);
|
|
||||||
void transform_volume_for_sample_on_channel(size_t sample_index, int channel, float volume);
|
|
||||||
|
|
||||||
void clamp();
|
|
||||||
|
|
||||||
void silence();
|
|
||||||
void silence(size_t start_sample, size_t end_sample);
|
|
||||||
void silence_bytes(size_t start_byte, size_t end_byte);
|
|
||||||
|
|
||||||
void set(int channel, const float* data, size_t sample_offset, size_t sample_length);
|
|
||||||
void set(int channel, const float* data, size_t sample_length)
|
|
||||||
{
|
|
||||||
set(channel, data, 0, sample_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void clamp_channel(int channel);
|
|
||||||
|
|
||||||
AudioParams audio_params_;
|
|
||||||
|
|
||||||
size_t sample_count_per_channel_;
|
|
||||||
|
|
||||||
std::vector< std::vector<float> > data_;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(olive::SampleBuffer)
|
|
||||||
|
|
||||||
#endif // SAMPLEBUFFER_H
|
|
||||||
@@ -16,11 +16,8 @@
|
|||||||
|
|
||||||
set(OLIVE_SOURCES
|
set(OLIVE_SOURCES
|
||||||
${OLIVE_SOURCES}
|
${OLIVE_SOURCES}
|
||||||
common/bezier.cpp
|
|
||||||
common/bezier.h
|
|
||||||
common/cancelableobject.h
|
common/cancelableobject.h
|
||||||
common/channellayout.h
|
common/channellayout.h
|
||||||
common/clamp.h
|
|
||||||
common/commandlineparser.cpp
|
common/commandlineparser.cpp
|
||||||
common/commandlineparser.h
|
common/commandlineparser.h
|
||||||
common/crashpadinterface.cpp
|
common/crashpadinterface.cpp
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
/***
|
|
||||||
|
|
||||||
Olive - Non-Linear Video Editor
|
|
||||||
Copyright (C) 2022 Olive Team
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "bezier.h"
|
|
||||||
|
|
||||||
#include <QtMath>
|
|
||||||
|
|
||||||
#include "common/clamp.h"
|
|
||||||
|
|
||||||
namespace olive {
|
|
||||||
|
|
||||||
Bezier::Bezier() :
|
|
||||||
x_(0),
|
|
||||||
y_(0),
|
|
||||||
cp1_x_(0),
|
|
||||||
cp1_y_(0),
|
|
||||||
cp2_x_(0),
|
|
||||||
cp2_y_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Bezier::Bezier(double x, double y) :
|
|
||||||
x_(x),
|
|
||||||
y_(y),
|
|
||||||
cp1_x_(0),
|
|
||||||
cp1_y_(0),
|
|
||||||
cp2_x_(0),
|
|
||||||
cp2_y_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Bezier::Bezier(double x, double y, double cp1_x, double cp1_y, double cp2_x, double cp2_y) :
|
|
||||||
x_(x),
|
|
||||||
y_(y),
|
|
||||||
cp1_x_(cp1_x),
|
|
||||||
cp1_y_(cp1_y),
|
|
||||||
cp2_x_(cp2_x),
|
|
||||||
cp2_y_(cp2_y)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
double Bezier::QuadraticXtoT(double x, double a, double b, double c)
|
|
||||||
{
|
|
||||||
// Clamp to prevent infinite loop
|
|
||||||
x = clamp(x, a, c);
|
|
||||||
|
|
||||||
return CalculateTFromX(false, x, a, b, c, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
double Bezier::QuadraticTtoY(double a, double b, double c, double t)
|
|
||||||
{
|
|
||||||
return qPow(1.0 - t, 2)*a + 2*(1.0 - t)*t*b + qPow(t, 2)*c;
|
|
||||||
}
|
|
||||||
|
|
||||||
double Bezier::CubicXtoT(double x, double a, double b, double c, double d)
|
|
||||||
{
|
|
||||||
// Clamp to prevent infinite loop
|
|
||||||
x = clamp(x, a, d);
|
|
||||||
|
|
||||||
return CalculateTFromX(true, x, a, b, c, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
double Bezier::CubicTtoY(double a, double b, double c, double d, double t)
|
|
||||||
{
|
|
||||||
return qPow(1.0 - t, 3)*a + 3*qPow(1.0 - t, 2)*t*b + 3*(1.0 - t)*qPow(t, 2)*c + qPow(t, 3)*d;
|
|
||||||
}
|
|
||||||
|
|
||||||
double Bezier::CalculateTFromX(bool cubic, double x, double a, double b, double c, double d)
|
|
||||||
{
|
|
||||||
double bottom = 0.0;
|
|
||||||
double top = 1.0;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (bottom == top) {
|
|
||||||
return bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
double mid = (bottom + top) * 0.5;
|
|
||||||
double test = cubic ? CubicTtoY(a, b, c, d, mid) : QuadraticTtoY(a, b, c, mid);
|
|
||||||
|
|
||||||
if (qAbs(test - x) < 0.000001) {
|
|
||||||
return mid;
|
|
||||||
} else if (x > test) {
|
|
||||||
bottom = mid;
|
|
||||||
} else {
|
|
||||||
top = mid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return qSNaN();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/***
|
|
||||||
|
|
||||||
Olive - Non-Linear Video Editor
|
|
||||||
Copyright (C) 2022 Olive Team
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef BEZIER_H
|
|
||||||
#define BEZIER_H
|
|
||||||
|
|
||||||
#include <QPointF>
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include "common/define.h"
|
|
||||||
|
|
||||||
namespace olive {
|
|
||||||
|
|
||||||
class Bezier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Bezier();
|
|
||||||
Bezier(double x, double y);
|
|
||||||
Bezier(double x, double y, double cp1_x, double cp1_y, double cp2_x, double cp2_y);
|
|
||||||
|
|
||||||
const double &x() const {return x_; }
|
|
||||||
const double &y() const {return y_; }
|
|
||||||
const double &cp1_x() const { return cp1_x_; }
|
|
||||||
const double &cp1_y() const { return cp1_y_; }
|
|
||||||
const double &cp2_x() const { return cp2_x_; }
|
|
||||||
const double &cp2_y() const { return cp2_y_; }
|
|
||||||
|
|
||||||
QPointF ToPointF() const
|
|
||||||
{
|
|
||||||
return QPointF(x_, y_);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF ControlPoint1ToPointF() const
|
|
||||||
{
|
|
||||||
return QPointF(cp1_x_, cp1_y_);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF ControlPoint2ToPointF() const
|
|
||||||
{
|
|
||||||
return QPointF(cp2_x_, cp2_y_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_x(const double &x) { x_ = x; }
|
|
||||||
void set_y(const double &y) { y_ = y; }
|
|
||||||
void set_cp1_x(const double &cp1_x) { cp1_x_ = cp1_x; }
|
|
||||||
void set_cp1_y(const double &cp1_y) { cp1_y_ = cp1_y; }
|
|
||||||
void set_cp2_x(const double &cp2_x) { cp2_x_ = cp2_x; }
|
|
||||||
void set_cp2_y(const double &cp2_y) { cp2_y_ = cp2_y; }
|
|
||||||
|
|
||||||
static double QuadraticXtoT(double x, double a, double b, double c);
|
|
||||||
|
|
||||||
static double QuadraticTtoY(double a, double b, double c, double t);
|
|
||||||
|
|
||||||
static double QuadraticXtoY(double x, const QPointF &a, const QPointF &b, const QPointF &c)
|
|
||||||
{
|
|
||||||
return QuadraticTtoY(a.y(), b.y(), c.y(), QuadraticXtoT(x, a.x(), b.x(), c.x()));
|
|
||||||
}
|
|
||||||
|
|
||||||
static double CubicXtoT(double x, double a, double b, double c, double d);
|
|
||||||
|
|
||||||
static double CubicTtoY(double a, double b, double c, double d, double t);
|
|
||||||
|
|
||||||
static double CubicXtoY(double x, const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d)
|
|
||||||
{
|
|
||||||
return CubicTtoY(a.y(), b.y(), c.y(), d.y(), CubicXtoT(x, a.x(), b.x(), c.x(), d.x()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static double CalculateTFromX(bool cubic, double x, double a, double b, double c, double d);
|
|
||||||
|
|
||||||
double x_;
|
|
||||||
double y_;
|
|
||||||
|
|
||||||
double cp1_x_;
|
|
||||||
double cp1_y_;
|
|
||||||
|
|
||||||
double cp2_x_;
|
|
||||||
double cp2_y_;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(olive::Bezier)
|
|
||||||
|
|
||||||
#endif // BEZIER_H
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/***
|
|
||||||
|
|
||||||
Olive - Non-Linear Video Editor
|
|
||||||
Copyright (C) 2022 Olive Team
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef CLAMP_H
|
|
||||||
#define CLAMP_H
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
/**
|
|
||||||
* @brief Clamp a value between a minimum and a maximum value
|
|
||||||
*
|
|
||||||
* Similar to using min() and max() functions, but performs both at once. If value is less than minimum, this returns
|
|
||||||
* minimum. If it is more than maximum, this returns maximum. Otherwise it returns value as-is.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* Will always return a value between minimum and maximum (inclusive).
|
|
||||||
*/
|
|
||||||
T clamp(T value, T minimum, T maximum) {
|
|
||||||
if (value < minimum) {
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value > maximum) {
|
|
||||||
return maximum;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CLAMP_H
|
|
||||||
+32
-32
@@ -41,70 +41,70 @@ AVPixelFormat FFmpegUtils::GetCompatiblePixelFormat(const AVPixelFormat &pix_fmt
|
|||||||
nullptr);
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioParams::Format FFmpegUtils::GetNativeSampleFormat(const AVSampleFormat &smp_fmt)
|
SampleFormat FFmpegUtils::GetNativeSampleFormat(const AVSampleFormat &smp_fmt)
|
||||||
{
|
{
|
||||||
switch (smp_fmt) {
|
switch (smp_fmt) {
|
||||||
case AV_SAMPLE_FMT_U8:
|
case AV_SAMPLE_FMT_U8:
|
||||||
return AudioParams::kFormatUnsigned8Packed;
|
return SampleFormat::U8;
|
||||||
case AV_SAMPLE_FMT_S16:
|
case AV_SAMPLE_FMT_S16:
|
||||||
return AudioParams::kFormatSigned16Packed;
|
return SampleFormat::S16;
|
||||||
case AV_SAMPLE_FMT_S32:
|
case AV_SAMPLE_FMT_S32:
|
||||||
return AudioParams::kFormatSigned32Packed;
|
return SampleFormat::S32;
|
||||||
case AV_SAMPLE_FMT_S64:
|
case AV_SAMPLE_FMT_S64:
|
||||||
return AudioParams::kFormatSigned64Packed;
|
return SampleFormat::S64;
|
||||||
case AV_SAMPLE_FMT_FLT:
|
case AV_SAMPLE_FMT_FLT:
|
||||||
return AudioParams::kFormatFloat32Packed;
|
return SampleFormat::F32;
|
||||||
case AV_SAMPLE_FMT_DBL:
|
case AV_SAMPLE_FMT_DBL:
|
||||||
return AudioParams::kFormatFloat64Packed;
|
return SampleFormat::F64;
|
||||||
case AV_SAMPLE_FMT_U8P :
|
case AV_SAMPLE_FMT_U8P :
|
||||||
return AudioParams::kFormatUnsigned8Planar;
|
return SampleFormat::U8P;
|
||||||
case AV_SAMPLE_FMT_S16P:
|
case AV_SAMPLE_FMT_S16P:
|
||||||
return AudioParams::kFormatSigned16Planar;
|
return SampleFormat::S16P;
|
||||||
case AV_SAMPLE_FMT_S32P:
|
case AV_SAMPLE_FMT_S32P:
|
||||||
return AudioParams::kFormatSigned32Planar;
|
return SampleFormat::S32P;
|
||||||
case AV_SAMPLE_FMT_S64P:
|
case AV_SAMPLE_FMT_S64P:
|
||||||
return AudioParams::kFormatSigned64Planar;
|
return SampleFormat::S64P;
|
||||||
case AV_SAMPLE_FMT_FLTP:
|
case AV_SAMPLE_FMT_FLTP:
|
||||||
return AudioParams::kFormatFloat32Planar;
|
return SampleFormat::F32P;
|
||||||
case AV_SAMPLE_FMT_DBLP:
|
case AV_SAMPLE_FMT_DBLP:
|
||||||
return AudioParams::kFormatFloat64Planar;
|
return SampleFormat::F64P;
|
||||||
case AV_SAMPLE_FMT_NONE:
|
case AV_SAMPLE_FMT_NONE:
|
||||||
case AV_SAMPLE_FMT_NB:
|
case AV_SAMPLE_FMT_NB:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AudioParams::kFormatInvalid;
|
return SampleFormat::INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVSampleFormat FFmpegUtils::GetFFmpegSampleFormat(const AudioParams::Format &smp_fmt)
|
AVSampleFormat FFmpegUtils::GetFFmpegSampleFormat(const SampleFormat &smp_fmt)
|
||||||
{
|
{
|
||||||
switch (smp_fmt) {
|
switch (smp_fmt) {
|
||||||
case AudioParams::kFormatUnsigned8Packed:
|
case SampleFormat::U8:
|
||||||
return AV_SAMPLE_FMT_U8;
|
return AV_SAMPLE_FMT_U8;
|
||||||
case AudioParams::kFormatSigned16Packed:
|
case SampleFormat::S16:
|
||||||
return AV_SAMPLE_FMT_S16;
|
return AV_SAMPLE_FMT_S16;
|
||||||
case AudioParams::kFormatSigned32Packed:
|
case SampleFormat::S32:
|
||||||
return AV_SAMPLE_FMT_S32;
|
return AV_SAMPLE_FMT_S32;
|
||||||
case AudioParams::kFormatSigned64Packed:
|
case SampleFormat::S64:
|
||||||
return AV_SAMPLE_FMT_S64;
|
return AV_SAMPLE_FMT_S64;
|
||||||
case AudioParams::kFormatFloat32Packed:
|
case SampleFormat::F32:
|
||||||
return AV_SAMPLE_FMT_FLT;
|
return AV_SAMPLE_FMT_FLT;
|
||||||
case AudioParams::kFormatFloat64Packed:
|
case SampleFormat::F64:
|
||||||
return AV_SAMPLE_FMT_DBL;
|
return AV_SAMPLE_FMT_DBL;
|
||||||
case AudioParams::kFormatUnsigned8Planar:
|
case SampleFormat::U8P:
|
||||||
return AV_SAMPLE_FMT_U8P;
|
return AV_SAMPLE_FMT_U8P;
|
||||||
case AudioParams::kFormatSigned16Planar:
|
case SampleFormat::S16P:
|
||||||
return AV_SAMPLE_FMT_S16P;
|
return AV_SAMPLE_FMT_S16P;
|
||||||
case AudioParams::kFormatSigned32Planar:
|
case SampleFormat::S32P:
|
||||||
return AV_SAMPLE_FMT_S32P;
|
return AV_SAMPLE_FMT_S32P;
|
||||||
case AudioParams::kFormatSigned64Planar:
|
case SampleFormat::S64P:
|
||||||
return AV_SAMPLE_FMT_S64P;
|
return AV_SAMPLE_FMT_S64P;
|
||||||
case AudioParams::kFormatFloat32Planar:
|
case SampleFormat::F32P:
|
||||||
return AV_SAMPLE_FMT_FLTP;
|
return AV_SAMPLE_FMT_FLTP;
|
||||||
case AudioParams::kFormatFloat64Planar:
|
case SampleFormat::F64P:
|
||||||
return AV_SAMPLE_FMT_DBLP;
|
return AV_SAMPLE_FMT_DBLP;
|
||||||
case AudioParams::kFormatInvalid:
|
case SampleFormat::INVALID:
|
||||||
case AudioParams::kFormatCount:
|
case SampleFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ AVPixelFormat FFmpegUtils::GetFFmpegPixelFormat(const PixelFormat &pix_fmt, int
|
|||||||
case PixelFormat::F16:
|
case PixelFormat::F16:
|
||||||
case PixelFormat::F32:
|
case PixelFormat::F32:
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (channel_layout == VideoParams::kRGBAChannelCount) {
|
} else if (channel_layout == VideoParams::kRGBAChannelCount) {
|
||||||
@@ -171,7 +171,7 @@ AVPixelFormat FFmpegUtils::GetFFmpegPixelFormat(const PixelFormat &pix_fmt, int
|
|||||||
case PixelFormat::F16:
|
case PixelFormat::F16:
|
||||||
case PixelFormat::F32:
|
case PixelFormat::F32:
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ PixelFormat FFmpegUtils::GetCompatiblePixelFormat(const PixelFormat &pix_fmt)
|
|||||||
case PixelFormat::F32:
|
case PixelFormat::F32:
|
||||||
return PixelFormat::U16;
|
return PixelFormat::U16;
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,14 @@ extern "C" {
|
|||||||
#include <libswscale/swscale.h>
|
#include <libswscale/swscale.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "render/audioparams.h"
|
#include <olive/core/core.h>
|
||||||
|
|
||||||
#include "render/videoparams.h"
|
#include "render/videoparams.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
class FFmpegUtils {
|
class FFmpegUtils {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -52,12 +55,12 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Returns a native sample format type for a given AVSampleFormat
|
* @brief Returns a native sample format type for a given AVSampleFormat
|
||||||
*/
|
*/
|
||||||
static AudioParams::Format GetNativeSampleFormat(const AVSampleFormat& smp_fmt);
|
static SampleFormat GetNativeSampleFormat(const AVSampleFormat& smp_fmt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns an FFmpeg sample format type for a given native type
|
* @brief Returns an FFmpeg sample format type for a given native type
|
||||||
*/
|
*/
|
||||||
static AVSampleFormat GetFFmpegSampleFormat(const AudioParams::Format &smp_fmt);
|
static AVSampleFormat GetFFmpegSampleFormat(const SampleFormat &smp_fmt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns an SWS_CS_* macro from an AVColorSpace enum member
|
* @brief Returns an SWS_CS_* macro from an AVColorSpace enum member
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ OCIO::BitDepth OCIOUtils::GetOCIOBitDepthFromPixelFormat(PixelFormat format)
|
|||||||
return OCIO::BIT_DEPTH_F32;
|
return OCIO::BIT_DEPTH_F32;
|
||||||
break;
|
break;
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
case PixelFormat::F32:
|
case PixelFormat::F32:
|
||||||
return OIIO::TypeDesc::FLOAT;
|
return OIIO::TypeDesc::FLOAT;
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,6 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include "common/clamp.h"
|
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
int QtUtils::QFontMetricsWidth(QFontMetrics fm, const QString& s) {
|
int QtUtils::QFontMetricsWidth(QFontMetrics fm, const QString& s) {
|
||||||
@@ -179,10 +177,10 @@ QColor QtUtils::toQColor(const core::Color &i)
|
|||||||
QColor c;
|
QColor c;
|
||||||
|
|
||||||
// QColor only supports values from 0.0 to 1.0 and are only used for UI representations
|
// QColor only supports values from 0.0 to 1.0 and are only used for UI representations
|
||||||
c.setRedF(clamp(i.red(), 0.0f, 1.0f));
|
c.setRedF(std::clamp(i.red(), 0.0f, 1.0f));
|
||||||
c.setGreenF(clamp(i.green(), 0.0f, 1.0f));
|
c.setGreenF(std::clamp(i.green(), 0.0f, 1.0f));
|
||||||
c.setBlueF(clamp(i.blue(), 0.0f, 1.0f));
|
c.setBlueF(std::clamp(i.blue(), 0.0f, 1.0f));
|
||||||
c.setAlphaF(clamp(i.alpha(), 0.0f, 1.0f));
|
c.setAlphaF(std::clamp(i.alpha(), 0.0f, 1.0f));
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,5 +89,8 @@ uint qHash(const core::TimeRange& r, uint seed = 0);
|
|||||||
Q_DECLARE_METATYPE(olive::core::rational);
|
Q_DECLARE_METATYPE(olive::core::rational);
|
||||||
Q_DECLARE_METATYPE(olive::core::Color);
|
Q_DECLARE_METATYPE(olive::core::Color);
|
||||||
Q_DECLARE_METATYPE(olive::core::TimeRange);
|
Q_DECLARE_METATYPE(olive::core::TimeRange);
|
||||||
|
Q_DECLARE_METATYPE(olive::core::Bezier);
|
||||||
|
Q_DECLARE_METATYPE(olive::core::AudioParams);
|
||||||
|
Q_DECLARE_METATYPE(olive::core::SampleBuffer);
|
||||||
|
|
||||||
#endif // QTVERSIONABSTRACTION_H
|
#endif // QTVERSIONABSTRACTION_H
|
||||||
|
|||||||
@@ -138,13 +138,13 @@ void Config::SetDefaults()
|
|||||||
|
|
||||||
SetEntryInternal(QStringLiteral("AudioOutputSampleRate"), NodeValue::kInt, 48000);
|
SetEntryInternal(QStringLiteral("AudioOutputSampleRate"), NodeValue::kInt, 48000);
|
||||||
SetEntryInternal(QStringLiteral("AudioOutputChannelLayout"), NodeValue::kInt, AV_CH_LAYOUT_STEREO);
|
SetEntryInternal(QStringLiteral("AudioOutputChannelLayout"), NodeValue::kInt, AV_CH_LAYOUT_STEREO);
|
||||||
SetEntryInternal(QStringLiteral("AudioOutputSampleFormat"), NodeValue::kInt, AudioParams::kFormatSigned16Packed);
|
SetEntryInternal(QStringLiteral("AudioOutputSampleFormat"), NodeValue::kText, QString::fromStdString(SampleFormat(SampleFormat::S16).to_string()));
|
||||||
|
|
||||||
SetEntryInternal(QStringLiteral("AudioRecordingFormat"), NodeValue::kInt, ExportFormat::kFormatWAV);
|
SetEntryInternal(QStringLiteral("AudioRecordingFormat"), NodeValue::kInt, ExportFormat::kFormatWAV);
|
||||||
SetEntryInternal(QStringLiteral("AudioRecordingCodec"), NodeValue::kInt, ExportCodec::kCodecPCM);
|
SetEntryInternal(QStringLiteral("AudioRecordingCodec"), NodeValue::kInt, ExportCodec::kCodecPCM);
|
||||||
SetEntryInternal(QStringLiteral("AudioRecordingSampleRate"), NodeValue::kInt, 48000);
|
SetEntryInternal(QStringLiteral("AudioRecordingSampleRate"), NodeValue::kInt, 48000);
|
||||||
SetEntryInternal(QStringLiteral("AudioRecordingChannelLayout"), NodeValue::kInt, AV_CH_LAYOUT_STEREO);
|
SetEntryInternal(QStringLiteral("AudioRecordingChannelLayout"), NodeValue::kInt, AV_CH_LAYOUT_STEREO);
|
||||||
SetEntryInternal(QStringLiteral("AudioRecordingSampleFormat"), NodeValue::kInt, AudioParams::kFormatSigned16Packed);
|
SetEntryInternal(QStringLiteral("AudioRecordingSampleFormat"), NodeValue::kText, QString::fromStdString(SampleFormat(SampleFormat::S16).to_string()));
|
||||||
SetEntryInternal(QStringLiteral("AudioRecordingBitRate"), NodeValue::kInt, 320);
|
SetEntryInternal(QStringLiteral("AudioRecordingBitRate"), NodeValue::kInt, 320);
|
||||||
|
|
||||||
SetEntryInternal(QStringLiteral("DiskCacheBehind"), NodeValue::kRational, QVariant::fromValue(rational(0)));
|
SetEntryInternal(QStringLiteral("DiskCacheBehind"), NodeValue::kRational, QVariant::fromValue(rational(0)));
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ PreferencesAudioTab::PreferencesAudioTab()
|
|||||||
|
|
||||||
output_fmt_combo_ = new SampleFormatComboBox();
|
output_fmt_combo_ = new SampleFormatComboBox();
|
||||||
output_fmt_combo_->SetPackedFormats();
|
output_fmt_combo_->SetPackedFormats();
|
||||||
output_fmt_combo_->SetSampleFormat(static_cast<AudioParams::Format>(OLIVE_CONFIG("AudioOutputSampleFormat").toInt()));
|
output_fmt_combo_->SetSampleFormat(SampleFormat::from_string(OLIVE_CONFIG("AudioOutputSampleFormat").toString().toStdString()));
|
||||||
output_param_layout->addWidget(output_fmt_combo_, output_row, 1);
|
output_param_layout->addWidget(output_fmt_combo_, output_row, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ PreferencesAudioTab::PreferencesAudioTab()
|
|||||||
record_options_->sample_rate_combobox()->SetSampleRate(OLIVE_CONFIG("AudioRecordingSampleRate").toInt());
|
record_options_->sample_rate_combobox()->SetSampleRate(OLIVE_CONFIG("AudioRecordingSampleRate").toInt());
|
||||||
record_options_->channel_layout_combobox()->SetChannelLayout(OLIVE_CONFIG("AudioRecordingChannelLayout").toULongLong());
|
record_options_->channel_layout_combobox()->SetChannelLayout(OLIVE_CONFIG("AudioRecordingChannelLayout").toULongLong());
|
||||||
record_options_->bit_rate_slider()->SetValue(OLIVE_CONFIG("AudioRecordingBitRate").toInt());
|
record_options_->bit_rate_slider()->SetValue(OLIVE_CONFIG("AudioRecordingBitRate").toInt());
|
||||||
record_options_->sample_format_combobox()->SetSampleFormat(static_cast<AudioParams::Format>(OLIVE_CONFIG("AudioRecordingSampleFormat").toInt()));
|
record_options_->sample_format_combobox()->SetSampleFormat(SampleFormat::from_string(OLIVE_CONFIG("AudioRecordingSampleFormat").toString().toStdString()));
|
||||||
recording_layout->addWidget(record_options_);
|
recording_layout->addWidget(record_options_);
|
||||||
|
|
||||||
connect(record_format_combo_, &ExportFormatComboBox::FormatChanged, record_options_, &ExportAudioTab::SetFormat);
|
connect(record_format_combo_, &ExportFormatComboBox::FormatChanged, record_options_, &ExportAudioTab::SetFormat);
|
||||||
@@ -182,14 +182,14 @@ void PreferencesAudioTab::Accept(MultiUndoCommand *command)
|
|||||||
|
|
||||||
OLIVE_CONFIG("AudioOutputSampleRate") = output_rate_combo_->GetSampleRate();
|
OLIVE_CONFIG("AudioOutputSampleRate") = output_rate_combo_->GetSampleRate();
|
||||||
OLIVE_CONFIG("AudioOutputChannelLayout") = QVariant::fromValue(output_ch_layout_combo_->GetChannelLayout());
|
OLIVE_CONFIG("AudioOutputChannelLayout") = QVariant::fromValue(output_ch_layout_combo_->GetChannelLayout());
|
||||||
OLIVE_CONFIG("AudioOutputSampleFormat") = output_fmt_combo_->GetSampleFormat();
|
OLIVE_CONFIG("AudioOutputSampleFormat") = QString::fromStdString(output_fmt_combo_->GetSampleFormat().to_string());
|
||||||
|
|
||||||
OLIVE_CONFIG("AudioRecordingFormat") = record_format_combo_->GetFormat();
|
OLIVE_CONFIG("AudioRecordingFormat") = record_format_combo_->GetFormat();
|
||||||
OLIVE_CONFIG("AudioRecordingCodec") = record_options_->GetCodec();
|
OLIVE_CONFIG("AudioRecordingCodec") = record_options_->GetCodec();
|
||||||
OLIVE_CONFIG("AudioRecordingSampleRate") = record_options_->sample_rate_combobox()->GetSampleRate();
|
OLIVE_CONFIG("AudioRecordingSampleRate") = record_options_->sample_rate_combobox()->GetSampleRate();
|
||||||
OLIVE_CONFIG("AudioRecordingChannelLayout") = QVariant::fromValue(record_options_->channel_layout_combobox()->GetChannelLayout());
|
OLIVE_CONFIG("AudioRecordingChannelLayout") = QVariant::fromValue(record_options_->channel_layout_combobox()->GetChannelLayout());
|
||||||
OLIVE_CONFIG("AudioRecordingBitRate") = QVariant::fromValue(record_options_->bit_rate_slider()->GetValue());
|
OLIVE_CONFIG("AudioRecordingBitRate") = QVariant::fromValue(record_options_->bit_rate_slider()->GetValue());
|
||||||
OLIVE_CONFIG("AudioRecordingSampleFormat") = record_options_->sample_format_combobox()->GetSampleFormat();
|
OLIVE_CONFIG("AudioRecordingSampleFormat") = QString::fromStdString(record_options_->sample_format_combobox()->GetSampleFormat().to_string());
|
||||||
|
|
||||||
emit AudioManager::instance()->OutputParamsChanged();
|
emit AudioManager::instance()->OutputParamsChanged();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ void SequenceDialog::accept()
|
|||||||
|
|
||||||
AudioParams audio_params = AudioParams(parameter_tab_->GetSelectedAudioSampleRate(),
|
AudioParams audio_params = AudioParams(parameter_tab_->GetSelectedAudioSampleRate(),
|
||||||
parameter_tab_->GetSelectedAudioChannelLayout(),
|
parameter_tab_->GetSelectedAudioChannelLayout(),
|
||||||
AudioParams::kInternalFormat);
|
Sequence::kDefaultSampleFormat);
|
||||||
|
|
||||||
if (make_undoable_) {
|
if (make_undoable_) {
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#include "common/filefunctions.h"
|
#include "common/filefunctions.h"
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/videoparams.h"
|
#include "render/videoparams.h"
|
||||||
#include "ui/icons/icons.h"
|
#include "ui/icons/icons.h"
|
||||||
#include "widget/menu/menu.h"
|
#include "widget/menu/menu.h"
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include "transition.h"
|
#include "transition.h"
|
||||||
|
|
||||||
#include "common/clamp.h"
|
|
||||||
#include "node/block/clip/clip.h"
|
#include "node/block/clip/clip.h"
|
||||||
#include "node/output/track/track.h"
|
#include "node/output/track/track.h"
|
||||||
#include "widget/slider/rationalslider.h"
|
#include "widget/slider/rationalslider.h"
|
||||||
@@ -126,7 +125,7 @@ double TransitionBlock::GetOutProgress(const double &time) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clamp(1.0 - (GetInternalTransitionTime(time) / out_offset().toDouble()), 0.0, 1.0);
|
return std::clamp(1.0 - (GetInternalTransitionTime(time) / out_offset().toDouble()), 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double TransitionBlock::GetInProgress(const double &time) const
|
double TransitionBlock::GetInProgress(const double &time) const
|
||||||
@@ -135,7 +134,7 @@ double TransitionBlock::GetInProgress(const double &time) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clamp((GetInternalTransitionTime(time) - out_offset().toDouble()) / in_offset().toDouble(), 0.0, 1.0);
|
return std::clamp((GetInternalTransitionTime(time) - out_offset().toDouble()) / in_offset().toDouble(), 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double TransitionBlock::GetInternalTransitionTime(const double &time) const
|
double TransitionBlock::GetInternalTransitionTime(const double &time) const
|
||||||
@@ -245,7 +244,7 @@ double TransitionBlock::TransformCurve(double linear) const
|
|||||||
linear *= linear;
|
linear *= linear;
|
||||||
break;
|
break;
|
||||||
case kLogarithmic:
|
case kLogarithmic:
|
||||||
linear = qSqrt(linear);
|
linear = std::sqrt(linear);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,9 +179,9 @@ void TransformDistortNode::GizmoDragStart(const NodeValueRow &row, double x, dou
|
|||||||
} else if (gizmo == rotation_gizmo_) {
|
} else if (gizmo == rotation_gizmo_) {
|
||||||
|
|
||||||
gizmo_anchor_pt_ = (row[kAnchorInput].toVec2() + gizmo->GetGlobals().nonsquare_resolution()/2).toPointF();
|
gizmo_anchor_pt_ = (row[kAnchorInput].toVec2() + gizmo->GetGlobals().nonsquare_resolution()/2).toPointF();
|
||||||
gizmo_start_angle_ = qAtan2(y - gizmo_anchor_pt_.y(), x - gizmo_anchor_pt_.x());
|
gizmo_start_angle_ = std::atan2(y - gizmo_anchor_pt_.y(), x - gizmo_anchor_pt_.x());
|
||||||
gizmo_last_angle_ = gizmo_start_angle_;
|
gizmo_last_angle_ = gizmo_start_angle_;
|
||||||
gizmo_last_alt_angle_ = qAtan2(x - gizmo_anchor_pt_.x(), y - gizmo_anchor_pt_.y());
|
gizmo_last_alt_angle_ = std::atan2(x - gizmo_anchor_pt_.x(), y - gizmo_anchor_pt_.y());
|
||||||
gizmo_rotate_wrap_ = 0;
|
gizmo_rotate_wrap_ = 0;
|
||||||
gizmo_rotate_last_dir_ = kDirectionNone;
|
gizmo_rotate_last_dir_ = kDirectionNone;
|
||||||
|
|
||||||
@@ -216,8 +216,8 @@ void TransformDistortNode::GizmoDragMove(double x, double y, const Qt::KeyboardM
|
|||||||
|
|
||||||
} else if (gizmo == rotation_gizmo_) {
|
} else if (gizmo == rotation_gizmo_) {
|
||||||
|
|
||||||
double raw_angle = qAtan2(y - gizmo_anchor_pt_.y(), x - gizmo_anchor_pt_.x());
|
double raw_angle = std::atan2(y - gizmo_anchor_pt_.y(), x - gizmo_anchor_pt_.x());
|
||||||
double alt_angle = qAtan2(x - gizmo_anchor_pt_.x(), y - gizmo_anchor_pt_.y());
|
double alt_angle = std::atan2(x - gizmo_anchor_pt_.x(), y - gizmo_anchor_pt_.y());
|
||||||
|
|
||||||
double current_angle = raw_angle;
|
double current_angle = raw_angle;
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ void PolygonGenerator::UpdateGizmoPositions(const NodeValueRow &row, const NodeG
|
|||||||
res = globals.square_resolution();
|
res = globals.square_resolution();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF half_res = res.toPointF()/2;
|
Imath::V2d half_res(res.x()/2, res.y()/2);
|
||||||
|
|
||||||
auto points = row[kPointsInput].toArray();
|
auto points = row[kPointsInput].toArray();
|
||||||
|
|
||||||
@@ -205,20 +205,20 @@ void PolygonGenerator::UpdateGizmoPositions(const NodeValueRow &row, const NodeG
|
|||||||
for (int i=0; i<pts_sz; i++) {
|
for (int i=0; i<pts_sz; i++) {
|
||||||
const Bezier &pt = points.at(i).toBezier();
|
const Bezier &pt = points.at(i).toBezier();
|
||||||
|
|
||||||
QPointF main = pt.ToPointF() + half_res;
|
Imath::V2d main = pt.to_vec() + half_res;
|
||||||
QPointF cp1 = main + pt.ControlPoint1ToPointF();
|
Imath::V2d cp1 = main + pt.control_point_1_to_vec();
|
||||||
QPointF cp2 = main + pt.ControlPoint2ToPointF();
|
Imath::V2d cp2 = main + pt.control_point_2_to_vec();
|
||||||
|
|
||||||
gizmo_position_handles_[i]->SetPoint(main);
|
gizmo_position_handles_[i]->SetPoint(QPointF(main.x, main.y));
|
||||||
|
|
||||||
gizmo_bezier_handles_[i*2]->SetPoint(cp1);
|
gizmo_bezier_handles_[i*2]->SetPoint(QPointF(cp1.x, cp1.y));
|
||||||
gizmo_bezier_lines_[i*2]->SetLine(QLineF(main, cp1));
|
gizmo_bezier_lines_[i*2]->SetLine(QLineF(QPointF(main.x, main.y), QPointF(cp1.x, cp1.y)));
|
||||||
gizmo_bezier_handles_[i*2+1]->SetPoint(cp2);
|
gizmo_bezier_handles_[i*2+1]->SetPoint(QPointF(cp2.x, cp2.y));
|
||||||
gizmo_bezier_lines_[i*2+1]->SetLine(QLineF(main, cp2));
|
gizmo_bezier_lines_[i*2+1]->SetLine(QLineF(QPointF(main.x, main.y), QPointF(cp2.x, cp2.y)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
poly_gizmo_->SetPath(GeneratePath(points, pts_sz).translated(half_res));
|
poly_gizmo_->SetPath(GeneratePath(points, pts_sz).translated(QPointF(half_res.x, half_res.y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderCode PolygonGenerator::GetShaderCode(const ShaderRequest &request) const
|
ShaderCode PolygonGenerator::GetShaderCode(const ShaderRequest &request) const
|
||||||
@@ -246,9 +246,11 @@ void PolygonGenerator::GizmoDragMove(double x, double y, const Qt::KeyboardModif
|
|||||||
|
|
||||||
void PolygonGenerator::AddPointToPath(QPainterPath *path, const Bezier &before, const Bezier &after)
|
void PolygonGenerator::AddPointToPath(QPainterPath *path, const Bezier &before, const Bezier &after)
|
||||||
{
|
{
|
||||||
path->cubicTo(before.ToPointF() + before.ControlPoint2ToPointF(),
|
Imath::V2d a = before.to_vec() + before.control_point_2_to_vec();
|
||||||
after.ToPointF() + after.ControlPoint1ToPointF(),
|
Imath::V2d b = after.to_vec() + after.control_point_1_to_vec();
|
||||||
after.ToPointF());
|
Imath::V2d c = after.to_vec();
|
||||||
|
|
||||||
|
path->cubicTo(QPointF(a.x, a.y), QPointF(b.x, b.y), QPointF(c.x, c.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
QPainterPath PolygonGenerator::GeneratePath(const NodeValueArray &points, int size)
|
QPainterPath PolygonGenerator::GeneratePath(const NodeValueArray &points, int size)
|
||||||
@@ -257,7 +259,8 @@ QPainterPath PolygonGenerator::GeneratePath(const NodeValueArray &points, int si
|
|||||||
|
|
||||||
if (!points.empty()) {
|
if (!points.empty()) {
|
||||||
const Bezier &first_pt = points.at(0).toBezier();
|
const Bezier &first_pt = points.at(0).toBezier();
|
||||||
path.moveTo(first_pt.ToPointF());
|
Imath::V2d v = first_pt.to_vec();
|
||||||
|
path.moveTo(QPointF(v.x, v.y));
|
||||||
|
|
||||||
for (int i=1; i<size; i++) {
|
for (int i=1; i<size; i++) {
|
||||||
AddPointToPath(&path, points.at(i-1).toBezier(), points.at(i).toBezier());
|
AddPointToPath(&path, points.at(i-1).toBezier(), points.at(i).toBezier());
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <QPainterPath>
|
#include <QPainterPath>
|
||||||
|
|
||||||
#include "common/bezier.h"
|
|
||||||
#include "node/generator/shape/generatorwithmerge.h"
|
#include "node/generator/shape/generatorwithmerge.h"
|
||||||
#include "node/gizmo/line.h"
|
#include "node/gizmo/line.h"
|
||||||
#include "node/gizmo/path.h"
|
#include "node/gizmo/path.h"
|
||||||
|
|||||||
@@ -20,12 +20,11 @@
|
|||||||
|
|
||||||
#include "textv2.h"
|
#include "textv2.h"
|
||||||
|
|
||||||
|
#include <olive/core/core.h>
|
||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
|
|
||||||
#include "common/cpuoptimize.h"
|
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
#define super ShapeNodeBase
|
#define super ShapeNodeBase
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <QVector2D>
|
#include <QVector2D>
|
||||||
|
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/loopmode.h"
|
#include "render/loopmode.h"
|
||||||
#include "render/videoparams.h"
|
#include "render/videoparams.h"
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include "inputimmediate.h"
|
#include "inputimmediate.h"
|
||||||
|
|
||||||
#include "common/bezier.h"
|
|
||||||
#include "common/lerp.h"
|
#include "common/lerp.h"
|
||||||
#include "common/tohex.h"
|
#include "common/tohex.h"
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <QMatrix4x4>
|
#include <QMatrix4x4>
|
||||||
#include <QVector2D>
|
#include <QVector2D>
|
||||||
|
|
||||||
#include "common/cpuoptimize.h"
|
|
||||||
#include "common/tohex.h"
|
#include "common/tohex.h"
|
||||||
#include "node/distort/transform/transformdistortnode.h"
|
#include "node/distort/transform/transformdistortnode.h"
|
||||||
|
|
||||||
@@ -595,7 +594,7 @@ T MathNodeBase::PerformAll(Operation operation, T a, U b)
|
|||||||
case kOpDivide:
|
case kOpDivide:
|
||||||
return a / b;
|
return a / b;
|
||||||
case kOpPower:
|
case kOpPower:
|
||||||
return qPow(a, b);
|
return std::pow(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
|
|||||||
@@ -83,22 +83,22 @@ void TrigonometryNode::Value(const NodeValueRow &value, const NodeGlobals &globa
|
|||||||
|
|
||||||
switch (static_cast<Operation>(GetStandardValue(kMethodIn).toInt())) {
|
switch (static_cast<Operation>(GetStandardValue(kMethodIn).toInt())) {
|
||||||
case kOpSine:
|
case kOpSine:
|
||||||
x = qSin(x);
|
x = std::sin(x);
|
||||||
break;
|
break;
|
||||||
case kOpCosine:
|
case kOpCosine:
|
||||||
x = qCos(x);
|
x = std::cos(x);
|
||||||
break;
|
break;
|
||||||
case kOpTangent:
|
case kOpTangent:
|
||||||
x = qTan(x);
|
x = std::tan(x);
|
||||||
break;
|
break;
|
||||||
case kOpArcSine:
|
case kOpArcSine:
|
||||||
x = qAsin(x);
|
x = std::asin(x);
|
||||||
break;
|
break;
|
||||||
case kOpArcCosine:
|
case kOpArcCosine:
|
||||||
x = qAcos(x);
|
x = std::acos(x);
|
||||||
break;
|
break;
|
||||||
case kOpArcTangent:
|
case kOpArcTangent:
|
||||||
x = qAtan(x);
|
x = std::atan(x);
|
||||||
break;
|
break;
|
||||||
case kOpHypSine:
|
case kOpHypSine:
|
||||||
x = std::sinh(x);
|
x = std::sinh(x);
|
||||||
|
|||||||
+11
-14
@@ -25,7 +25,6 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
#include "common/bezier.h"
|
|
||||||
#include "common/lerp.h"
|
#include "common/lerp.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
@@ -484,31 +483,29 @@ QVariant Node::GetSplitValueAtTimeOnTrack(const QString &input, const rational &
|
|||||||
|
|
||||||
// Perform a cubic bezier with two control points
|
// Perform a cubic bezier with two control points
|
||||||
interpolated = Bezier::CubicXtoY(time.toDouble(),
|
interpolated = Bezier::CubicXtoY(time.toDouble(),
|
||||||
QPointF(before->time().toDouble(), before_val),
|
Imath::V2d(before->time().toDouble(), before_val),
|
||||||
QPointF(before->time().toDouble() + before->valid_bezier_control_out().x(), before_val + before->valid_bezier_control_out().y()),
|
Imath::V2d(before->time().toDouble() + before->valid_bezier_control_out().x(), before_val + before->valid_bezier_control_out().y()),
|
||||||
QPointF(after->time().toDouble() + after->valid_bezier_control_in().x(), after_val + after->valid_bezier_control_in().y()),
|
Imath::V2d(after->time().toDouble() + after->valid_bezier_control_in().x(), after_val + after->valid_bezier_control_in().y()),
|
||||||
QPointF(after->time().toDouble(), after_val));
|
Imath::V2d(after->time().toDouble(), after_val));
|
||||||
|
|
||||||
} else if (before->type() == NodeKeyframe::kBezier || after->type() == NodeKeyframe::kBezier) {
|
} else if (before->type() == NodeKeyframe::kBezier || after->type() == NodeKeyframe::kBezier) {
|
||||||
// Perform a quadratic bezier with only one control point
|
// Perform a quadratic bezier with only one control point
|
||||||
|
|
||||||
QPointF control_point;
|
Imath::V2d control_point;
|
||||||
|
|
||||||
if (before->type() == NodeKeyframe::kBezier) {
|
if (before->type() == NodeKeyframe::kBezier) {
|
||||||
control_point = before->valid_bezier_control_out();
|
control_point.x = (before->valid_bezier_control_out().x() + before->time().toDouble());
|
||||||
control_point.setX(control_point.x() + before->time().toDouble());
|
control_point.y = (before->valid_bezier_control_out().y() + before_val);
|
||||||
control_point.setY(control_point.y() + before_val);
|
|
||||||
} else {
|
} else {
|
||||||
control_point = after->valid_bezier_control_in();
|
control_point.x = (after->valid_bezier_control_in().x() + after->time().toDouble());
|
||||||
control_point.setX(control_point.x() + after->time().toDouble());
|
control_point.y = (after->valid_bezier_control_in().y() + after_val);
|
||||||
control_point.setY(control_point.y() + after_val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interpolate value using quadratic beziers
|
// Interpolate value using quadratic beziers
|
||||||
interpolated = Bezier::QuadraticXtoY(time.toDouble(),
|
interpolated = Bezier::QuadraticXtoY(time.toDouble(),
|
||||||
QPointF(before->time().toDouble(), before_val),
|
Imath::V2d(before->time().toDouble(), before_val),
|
||||||
control_point,
|
control_point,
|
||||||
QPointF(after->time().toDouble(), after_val));
|
Imath::V2d(after->time().toDouble(), after_val));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// To have arrived here, the keyframes must both be linear
|
// To have arrived here, the keyframes must both be linear
|
||||||
|
|||||||
@@ -29,14 +29,12 @@
|
|||||||
#include <QXmlStreamWriter>
|
#include <QXmlStreamWriter>
|
||||||
|
|
||||||
#include "codec/frame.h"
|
#include "codec/frame.h"
|
||||||
#include "codec/samplebuffer.h"
|
|
||||||
#include "common/xmlutils.h"
|
#include "common/xmlutils.h"
|
||||||
#include "node/gizmo/draggable.h"
|
#include "node/gizmo/draggable.h"
|
||||||
#include "node/globals.h"
|
#include "node/globals.h"
|
||||||
#include "node/keyframe.h"
|
#include "node/keyframe.h"
|
||||||
#include "node/inputimmediate.h"
|
#include "node/inputimmediate.h"
|
||||||
#include "node/param.h"
|
#include "node/param.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/audioplaybackcache.h"
|
#include "render/audioplaybackcache.h"
|
||||||
#include "render/audiowaveformcache.h"
|
#include "render/audiowaveformcache.h"
|
||||||
#include "render/framehashcache.h"
|
#include "render/framehashcache.h"
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ const QString ViewerOutput::kSubtitleParamsInput = QStringLiteral("subtitle_para
|
|||||||
const QString ViewerOutput::kTextureInput = QStringLiteral("tex_in");
|
const QString ViewerOutput::kTextureInput = QStringLiteral("tex_in");
|
||||||
const QString ViewerOutput::kSamplesInput = QStringLiteral("samples_in");
|
const QString ViewerOutput::kSamplesInput = QStringLiteral("samples_in");
|
||||||
|
|
||||||
|
const SampleFormat ViewerOutput::kDefaultSampleFormat = SampleFormat::F32P;
|
||||||
|
|
||||||
#define super Node
|
#define super Node
|
||||||
|
|
||||||
ViewerOutput::ViewerOutput(bool create_buffer_inputs, bool create_default_streams) :
|
ViewerOutput::ViewerOutput(bool create_buffer_inputs, bool create_default_streams) :
|
||||||
@@ -215,7 +217,7 @@ void ViewerOutput::set_default_parameters()
|
|||||||
SetAudioParams(AudioParams(
|
SetAudioParams(AudioParams(
|
||||||
OLIVE_CONFIG("DefaultSequenceAudioFrequency").toInt(),
|
OLIVE_CONFIG("DefaultSequenceAudioFrequency").toInt(),
|
||||||
OLIVE_CONFIG("DefaultSequenceAudioLayout").toULongLong(),
|
OLIVE_CONFIG("DefaultSequenceAudioLayout").toULongLong(),
|
||||||
AudioParams::kInternalFormat
|
kDefaultSampleFormat
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,7 +520,7 @@ void ViewerOutput::set_parameters_from_footage(const QVector<ViewerOutput *> foo
|
|||||||
|
|
||||||
if (!audio_streams.isEmpty()) {
|
if (!audio_streams.isEmpty()) {
|
||||||
const AudioParams& s = audio_streams.first();
|
const AudioParams& s = audio_streams.first();
|
||||||
SetAudioParams(AudioParams(s.sample_rate(), s.channel_layout(), AudioParams::kInternalFormat));
|
SetAudioParams(AudioParams(s.sample_rate(), s.channel_layout(), kDefaultSampleFormat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include "codec/encoder.h"
|
#include "codec/encoder.h"
|
||||||
#include "node/node.h"
|
#include "node/node.h"
|
||||||
#include "node/output/track/track.h"
|
#include "node/output/track/track.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/audioplaybackcache.h"
|
#include "render/audioplaybackcache.h"
|
||||||
#include "render/framehashcache.h"
|
#include "render/framehashcache.h"
|
||||||
#include "render/subtitleparams.h"
|
#include "render/subtitleparams.h"
|
||||||
@@ -200,6 +199,8 @@ public:
|
|||||||
static const QString kTextureInput;
|
static const QString kTextureInput;
|
||||||
static const QString kSamplesInput;
|
static const QString kSamplesInput;
|
||||||
|
|
||||||
|
static const SampleFormat kDefaultSampleFormat;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void FrameRateChanged(const rational&);
|
void FrameRateChanged(const rational&);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include "codec/decoder.h"
|
#include "codec/decoder.h"
|
||||||
#include "common/clamp.h"
|
|
||||||
#include "common/filefunctions.h"
|
#include "common/filefunctions.h"
|
||||||
#include "common/qtutils.h"
|
#include "common/qtutils.h"
|
||||||
#include "common/xmlutils.h"
|
#include "common/xmlutils.h"
|
||||||
@@ -352,7 +351,7 @@ rational Footage::AdjustTimeByLoopMode(rational time, LoopMode loop_mode, const
|
|||||||
break;
|
break;
|
||||||
case LoopMode::kLoopModeClamp:
|
case LoopMode::kLoopModeClamp:
|
||||||
// Clamp footage time to length
|
// Clamp footage time to length
|
||||||
time = clamp(time, rational(0), length - timebase);
|
time = std::clamp(time, rational(0), length - timebase);
|
||||||
break;
|
break;
|
||||||
case LoopMode::kLoopModeLoop:
|
case LoopMode::kLoopModeLoop:
|
||||||
// Loop footage time around job length
|
// Loop footage time around job length
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
#include "codec/decoder.h"
|
#include "codec/decoder.h"
|
||||||
#include "footagedescription.h"
|
#include "footagedescription.h"
|
||||||
#include "node/output/viewer/viewer.h"
|
#include "node/output/viewer/viewer.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/cancelatom.h"
|
#include "render/cancelatom.h"
|
||||||
#include "render/videoparams.h"
|
#include "render/videoparams.h"
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <QXmlStreamWriter>
|
#include <QXmlStreamWriter>
|
||||||
|
|
||||||
#include "common/xmlutils.h"
|
#include "common/xmlutils.h"
|
||||||
|
#include "node/project/serializer/typeserializer.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
@@ -74,8 +75,7 @@ bool FootageDescription::Load(const QString &filename)
|
|||||||
vp.Load(&reader);
|
vp.Load(&reader);
|
||||||
AddVideoStream(vp);
|
AddVideoStream(vp);
|
||||||
} else if (reader.name() == QStringLiteral("audio")) {
|
} else if (reader.name() == QStringLiteral("audio")) {
|
||||||
AudioParams ap;
|
AudioParams ap = TypeSerializer::LoadAudioParams(&reader);
|
||||||
ap.Load(&reader);
|
|
||||||
AddAudioStream(ap);
|
AddAudioStream(ap);
|
||||||
} else if (reader.name() == QStringLiteral("subtitle")) {
|
} else if (reader.name() == QStringLiteral("subtitle")) {
|
||||||
SubtitleParams sp;
|
SubtitleParams sp;
|
||||||
@@ -136,7 +136,7 @@ bool FootageDescription::Save(const QString &filename) const
|
|||||||
|
|
||||||
foreach (const AudioParams& ap, audio_streams_) {
|
foreach (const AudioParams& ap, audio_streams_) {
|
||||||
writer.writeStartElement(QStringLiteral("audio"));
|
writer.writeStartElement(QStringLiteral("audio"));
|
||||||
ap.Save(&writer);
|
TypeSerializer::SaveAudioParams(&writer, ap);
|
||||||
writer.writeEndElement(); // audio
|
writer.writeEndElement(); // audio
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#define FOOTAGEDESCRIPTION_H
|
#define FOOTAGEDESCRIPTION_H
|
||||||
|
|
||||||
#include "node/output/track/track.h"
|
#include "node/output/track/track.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/subtitleparams.h"
|
#include "render/subtitleparams.h"
|
||||||
#include "render/videoparams.h"
|
#include "render/videoparams.h"
|
||||||
|
|
||||||
|
|||||||
@@ -29,5 +29,9 @@ set(OLIVE_SOURCES
|
|||||||
node/project/serializer/serializer211228.h
|
node/project/serializer/serializer211228.h
|
||||||
node/project/serializer/serializer220403.cpp
|
node/project/serializer/serializer220403.cpp
|
||||||
node/project/serializer/serializer220403.h
|
node/project/serializer/serializer220403.h
|
||||||
|
|
||||||
|
node/project/serializer/typeserializer.cpp
|
||||||
|
node/project/serializer/typeserializer.h
|
||||||
|
|
||||||
PARENT_SCOPE
|
PARENT_SCOPE
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,10 +21,11 @@
|
|||||||
#ifndef PROJECTSERIALIZER_H
|
#ifndef PROJECTSERIALIZER_H
|
||||||
#define PROJECTSERIALIZER_H
|
#define PROJECTSERIALIZER_H
|
||||||
|
|
||||||
#include <QIODevice>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/define.h"
|
#include "common/define.h"
|
||||||
#include "node/project/project.h"
|
#include "node/project/project.h"
|
||||||
|
#include "typeserializer.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
|||||||
@@ -328,8 +328,7 @@ void ProjectSerializer210528::LoadImmediate(QXmlStreamReader *reader, Node *node
|
|||||||
vp.Load(reader);
|
vp.Load(reader);
|
||||||
value_on_track = QVariant::fromValue(vp);
|
value_on_track = QVariant::fromValue(vp);
|
||||||
} else if (data_type == NodeValue::kAudioParams) {
|
} else if (data_type == NodeValue::kAudioParams) {
|
||||||
AudioParams ap;
|
AudioParams ap = TypeSerializer::LoadAudioParams(reader);
|
||||||
ap.Load(reader);
|
|
||||||
value_on_track = QVariant::fromValue(ap);
|
value_on_track = QVariant::fromValue(ap);
|
||||||
} else {
|
} else {
|
||||||
QString value_text = reader->readElementText();
|
QString value_text = reader->readElementText();
|
||||||
|
|||||||
@@ -325,8 +325,7 @@ void ProjectSerializer210907::LoadImmediate(QXmlStreamReader *reader, Node *node
|
|||||||
vp.Load(reader);
|
vp.Load(reader);
|
||||||
value_on_track = QVariant::fromValue(vp);
|
value_on_track = QVariant::fromValue(vp);
|
||||||
} else if (data_type == NodeValue::kAudioParams) {
|
} else if (data_type == NodeValue::kAudioParams) {
|
||||||
AudioParams ap;
|
AudioParams ap = TypeSerializer::LoadAudioParams(reader);
|
||||||
ap.Load(reader);
|
|
||||||
value_on_track = QVariant::fromValue(ap);
|
value_on_track = QVariant::fromValue(ap);
|
||||||
} else {
|
} else {
|
||||||
QString value_text = reader->readElementText();
|
QString value_text = reader->readElementText();
|
||||||
|
|||||||
@@ -375,8 +375,7 @@ void ProjectSerializer211228::LoadImmediate(QXmlStreamReader *reader, Node *node
|
|||||||
vp.Load(reader);
|
vp.Load(reader);
|
||||||
value_on_track = QVariant::fromValue(vp);
|
value_on_track = QVariant::fromValue(vp);
|
||||||
} else if (data_type == NodeValue::kAudioParams) {
|
} else if (data_type == NodeValue::kAudioParams) {
|
||||||
AudioParams ap;
|
AudioParams ap = TypeSerializer::LoadAudioParams(reader);
|
||||||
ap.Load(reader);
|
|
||||||
value_on_track = QVariant::fromValue(ap);
|
value_on_track = QVariant::fromValue(ap);
|
||||||
} else {
|
} else {
|
||||||
QString value_text = reader->readElementText();
|
QString value_text = reader->readElementText();
|
||||||
|
|||||||
@@ -774,8 +774,7 @@ void ProjectSerializer220403::LoadImmediate(QXmlStreamReader *reader, Node *node
|
|||||||
vp.Load(reader);
|
vp.Load(reader);
|
||||||
value_on_track = QVariant::fromValue(vp);
|
value_on_track = QVariant::fromValue(vp);
|
||||||
} else if (data_type == NodeValue::kAudioParams) {
|
} else if (data_type == NodeValue::kAudioParams) {
|
||||||
AudioParams ap;
|
AudioParams ap = TypeSerializer::LoadAudioParams(reader);
|
||||||
ap.Load(reader);
|
|
||||||
value_on_track = QVariant::fromValue(ap);
|
value_on_track = QVariant::fromValue(ap);
|
||||||
} else {
|
} else {
|
||||||
QString value_text = reader->readElementText();
|
QString value_text = reader->readElementText();
|
||||||
@@ -857,7 +856,7 @@ void ProjectSerializer220403::SaveImmediate(QXmlStreamWriter *writer, Node *node
|
|||||||
if (data_type == NodeValue::kVideoParams) {
|
if (data_type == NodeValue::kVideoParams) {
|
||||||
v.value<VideoParams>().Save(writer);
|
v.value<VideoParams>().Save(writer);
|
||||||
} else if (data_type == NodeValue::kAudioParams) {
|
} else if (data_type == NodeValue::kAudioParams) {
|
||||||
v.value<AudioParams>().Save(writer);
|
TypeSerializer::SaveAudioParams(writer, v.value<AudioParams>());
|
||||||
} else {
|
} else {
|
||||||
writer->writeCharacters(NodeValue::ValueToString(data_type, v, true));
|
writer->writeCharacters(NodeValue::ValueToString(data_type, v, true));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/***
|
||||||
|
|
||||||
|
Olive - Non-Linear Video Editor
|
||||||
|
Copyright (C) 2023 Olive Team
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include "typeserializer.h"
|
||||||
|
|
||||||
|
namespace olive {
|
||||||
|
|
||||||
|
AudioParams TypeSerializer::LoadAudioParams(QXmlStreamReader *reader)
|
||||||
|
{
|
||||||
|
AudioParams a;
|
||||||
|
|
||||||
|
while (XMLReadNextStartElement(reader)) {
|
||||||
|
if (reader->name() == QStringLiteral("samplerate")) {
|
||||||
|
a.set_sample_rate(reader->readElementText().toInt());
|
||||||
|
} else if (reader->name() == QStringLiteral("channellayout")) {
|
||||||
|
a.set_channel_layout(reader->readElementText().toULongLong());
|
||||||
|
} else if (reader->name() == QStringLiteral("format")) {
|
||||||
|
a.set_format(SampleFormat::from_string(reader->readElementText().toStdString()));
|
||||||
|
} else if (reader->name() == QStringLiteral("enabled")) {
|
||||||
|
a.set_enabled(reader->readElementText().toInt());
|
||||||
|
} else if (reader->name() == QStringLiteral("streamindex")) {
|
||||||
|
a.set_stream_index(reader->readElementText().toInt());
|
||||||
|
} else if (reader->name() == QStringLiteral("duration")) {
|
||||||
|
a.set_duration(reader->readElementText().toLongLong());
|
||||||
|
} else if (reader->name() == QStringLiteral("timebase")) {
|
||||||
|
a.set_time_base(rational::fromString(reader->readElementText().toStdString()));
|
||||||
|
} else {
|
||||||
|
reader->skipCurrentElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeSerializer::SaveAudioParams(QXmlStreamWriter *writer, const AudioParams &a)
|
||||||
|
{
|
||||||
|
writer->writeTextElement(QStringLiteral("samplerate"), QString::number(a.sample_rate()));
|
||||||
|
writer->writeTextElement(QStringLiteral("channellayout"), QString::number(a.channel_layout()));
|
||||||
|
writer->writeTextElement(QStringLiteral("format"), QString::fromStdString(a.format().to_string()));
|
||||||
|
writer->writeTextElement(QStringLiteral("enabled"), QString::number(a.enabled()));
|
||||||
|
writer->writeTextElement(QStringLiteral("streamindex"), QString::number(a.stream_index()));
|
||||||
|
writer->writeTextElement(QStringLiteral("duration"), QString::number(a.duration()));
|
||||||
|
writer->writeTextElement(QStringLiteral("timebase"), QString::fromStdString(a.time_base().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/***
|
/***
|
||||||
|
|
||||||
Olive - Non-Linear Video Editor
|
Olive - Non-Linear Video Editor
|
||||||
Copyright (C) 2022 Olive Team
|
Copyright (C) 2023 Olive Team
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,13 +18,29 @@
|
|||||||
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#ifndef CPUOPTIMIZE_H
|
#ifndef TYPESERIALIZER_H
|
||||||
#define CPUOPTIMIZE_H
|
#define TYPESERIALIZER_H
|
||||||
|
|
||||||
#if defined(Q_PROCESSOR_X86)
|
#include <olive/core/core.h>
|
||||||
#include <xmmintrin.h>
|
#include <QXmlStreamReader>
|
||||||
#elif defined(Q_PROCESSOR_ARM)
|
#include <QXmlStreamWriter>
|
||||||
#include <sse2neon.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // CPUOPTIMIZE_H
|
#include "common/xmlutils.h"
|
||||||
|
|
||||||
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
|
class TypeSerializer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TypeSerializer() = default;
|
||||||
|
|
||||||
|
static AudioParams LoadAudioParams(QXmlStreamReader *reader);
|
||||||
|
static void SaveAudioParams(QXmlStreamWriter *writer, const AudioParams &a);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TYPESERIALIZER_H
|
||||||
@@ -26,9 +26,7 @@
|
|||||||
#include <QVector3D>
|
#include <QVector3D>
|
||||||
#include <QVector4D>
|
#include <QVector4D>
|
||||||
|
|
||||||
#include "common/bezier.h"
|
|
||||||
#include "common/tohex.h"
|
#include "common/tohex.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/subtitleparams.h"
|
#include "render/subtitleparams.h"
|
||||||
#include "render/videoparams.h"
|
#include "render/videoparams.h"
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,6 @@
|
|||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include "codec/samplebuffer.h"
|
|
||||||
#include "common/bezier.h"
|
|
||||||
#include "common/qtutils.h"
|
#include "common/qtutils.h"
|
||||||
#include "node/splitvalue.h"
|
#include "node/splitvalue.h"
|
||||||
#include "render/texture.h"
|
#include "render/texture.h"
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ add_subdirectory(opengl)
|
|||||||
|
|
||||||
set(OLIVE_SOURCES
|
set(OLIVE_SOURCES
|
||||||
${OLIVE_SOURCES}
|
${OLIVE_SOURCES}
|
||||||
render/audioparams.cpp
|
|
||||||
render/audioparams.h
|
|
||||||
render/audioplaybackcache.cpp
|
render/audioplaybackcache.cpp
|
||||||
render/audioplaybackcache.h
|
render/audioplaybackcache.h
|
||||||
render/audiowaveformcache.cpp
|
render/audiowaveformcache.cpp
|
||||||
|
|||||||
@@ -1,358 +0,0 @@
|
|||||||
/***
|
|
||||||
|
|
||||||
Olive - Non-Linear Video Editor
|
|
||||||
Copyright (C) 2022 Olive Team
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "audioparams.h"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <libavformat/avformat.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
|
|
||||||
#include "common/xmlutils.h"
|
|
||||||
|
|
||||||
namespace olive {
|
|
||||||
|
|
||||||
const QVector<int> AudioParams::kSupportedSampleRates = {
|
|
||||||
8000, // 8000 Hz
|
|
||||||
11025, // 11025 Hz
|
|
||||||
16000, // 16000 Hz
|
|
||||||
22050, // 22050 Hz
|
|
||||||
24000, // 24000 Hz
|
|
||||||
32000, // 32000 Hz
|
|
||||||
44100, // 44100 Hz
|
|
||||||
48000, // 48000 Hz
|
|
||||||
88200, // 88200 Hz
|
|
||||||
96000 // 96000 Hz
|
|
||||||
};
|
|
||||||
|
|
||||||
const QVector<uint64_t> AudioParams::kSupportedChannelLayouts = {
|
|
||||||
AV_CH_LAYOUT_MONO,
|
|
||||||
AV_CH_LAYOUT_STEREO,
|
|
||||||
AV_CH_LAYOUT_2_1,
|
|
||||||
AV_CH_LAYOUT_5POINT1,
|
|
||||||
AV_CH_LAYOUT_7POINT1
|
|
||||||
};
|
|
||||||
|
|
||||||
const AudioParams::Format AudioParams::kInternalFormat = AudioParams::kFormatFloat32Planar;
|
|
||||||
|
|
||||||
bool AudioParams::operator==(const AudioParams &other) const
|
|
||||||
{
|
|
||||||
return (format() == other.format()
|
|
||||||
&& sample_rate() == other.sample_rate()
|
|
||||||
&& time_base() == other.time_base()
|
|
||||||
&& channel_layout() == other.channel_layout());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioParams::operator!=(const AudioParams &other) const
|
|
||||||
{
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 AudioParams::time_to_bytes(const double &time) const
|
|
||||||
{
|
|
||||||
return time_to_bytes_per_channel(time) * channel_count();
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 AudioParams::time_to_bytes(const rational &time) const
|
|
||||||
{
|
|
||||||
return time_to_bytes(time.toDouble());
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 AudioParams::time_to_bytes_per_channel(const double &time) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(is_valid());
|
|
||||||
|
|
||||||
return qint64(time_to_samples(time)) * bytes_per_sample_per_channel();
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 AudioParams::time_to_bytes_per_channel(const rational &time) const
|
|
||||||
{
|
|
||||||
return time_to_bytes_per_channel(time.toDouble());
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 AudioParams::time_to_samples(const double &time) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(is_valid());
|
|
||||||
|
|
||||||
// NOTE: Not sure if we should round or ceil, but I've gotten better results with ceil.
|
|
||||||
// Specifically, we seem to occasionally get straggler ranges that never cache with round.
|
|
||||||
return qCeil(double(sample_rate()) * time);
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 AudioParams::time_to_samples(const rational &time) const
|
|
||||||
{
|
|
||||||
return time_to_samples(time.toDouble());
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 AudioParams::samples_to_bytes(const qint64 &samples) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(is_valid());
|
|
||||||
|
|
||||||
return samples_to_bytes_per_channel(samples) * channel_count();
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 AudioParams::samples_to_bytes_per_channel(const qint64 &samples) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(is_valid());
|
|
||||||
|
|
||||||
return samples * bytes_per_sample_per_channel();
|
|
||||||
}
|
|
||||||
|
|
||||||
rational AudioParams::samples_to_time(const qint64 &samples) const
|
|
||||||
{
|
|
||||||
return sample_rate_as_time_base() * samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 AudioParams::bytes_to_samples(const qint64 &bytes) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(is_valid());
|
|
||||||
|
|
||||||
return bytes / (channel_count() * bytes_per_sample_per_channel());
|
|
||||||
}
|
|
||||||
|
|
||||||
rational AudioParams::bytes_to_time(const qint64 &bytes) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(is_valid());
|
|
||||||
|
|
||||||
return samples_to_time(bytes_to_samples(bytes));
|
|
||||||
}
|
|
||||||
|
|
||||||
rational AudioParams::bytes_per_channel_to_time(const qint64 &bytes) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(is_valid());
|
|
||||||
|
|
||||||
return samples_to_time(bytes_to_samples(bytes * channel_count()));
|
|
||||||
}
|
|
||||||
|
|
||||||
int AudioParams::channel_count() const
|
|
||||||
{
|
|
||||||
return channel_count_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AudioParams::bytes_per_sample_per_channel() const
|
|
||||||
{
|
|
||||||
switch (format_) {
|
|
||||||
case kFormatUnsigned8Packed:
|
|
||||||
case kFormatUnsigned8Planar:
|
|
||||||
return 1;
|
|
||||||
case kFormatSigned16Packed:
|
|
||||||
case kFormatSigned16Planar:
|
|
||||||
return 2;
|
|
||||||
case kFormatSigned32Packed:
|
|
||||||
case kFormatSigned32Planar:
|
|
||||||
case kFormatFloat32Packed:
|
|
||||||
case kFormatFloat32Planar:
|
|
||||||
return 4;
|
|
||||||
case kFormatSigned64Packed:
|
|
||||||
case kFormatSigned64Planar:
|
|
||||||
case kFormatFloat64Packed:
|
|
||||||
case kFormatFloat64Planar:
|
|
||||||
return 8;
|
|
||||||
case kFormatInvalid:
|
|
||||||
case kFormatCount:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AudioParams::bits_per_sample() const
|
|
||||||
{
|
|
||||||
return bytes_per_sample_per_channel() * 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioParams::is_valid() const
|
|
||||||
{
|
|
||||||
return (!time_base().isNull()
|
|
||||||
&& channel_layout() > 0
|
|
||||||
&& format_ > kFormatInvalid
|
|
||||||
&& format_ < kFormatCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioParams::Load(QXmlStreamReader *reader)
|
|
||||||
{
|
|
||||||
while (XMLReadNextStartElement(reader)) {
|
|
||||||
if (reader->name() == QStringLiteral("samplerate")) {
|
|
||||||
set_sample_rate(reader->readElementText().toInt());
|
|
||||||
} else if (reader->name() == QStringLiteral("channellayout")) {
|
|
||||||
set_channel_layout(reader->readElementText().toULongLong());
|
|
||||||
} else if (reader->name() == QStringLiteral("format")) {
|
|
||||||
set_format(static_cast<AudioParams::Format>(reader->readElementText().toInt()));
|
|
||||||
} else if (reader->name() == QStringLiteral("enabled")) {
|
|
||||||
set_enabled(reader->readElementText().toInt());
|
|
||||||
} else if (reader->name() == QStringLiteral("streamindex")) {
|
|
||||||
set_stream_index(reader->readElementText().toInt());
|
|
||||||
} else if (reader->name() == QStringLiteral("duration")) {
|
|
||||||
set_duration(reader->readElementText().toLongLong());
|
|
||||||
} else if (reader->name() == QStringLiteral("timebase")) {
|
|
||||||
set_time_base(rational::fromString(reader->readElementText().toStdString()));
|
|
||||||
} else {
|
|
||||||
reader->skipCurrentElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioParams::Save(QXmlStreamWriter *writer) const
|
|
||||||
{
|
|
||||||
writer->writeTextElement(QStringLiteral("samplerate"), QString::number(sample_rate_));
|
|
||||||
writer->writeTextElement(QStringLiteral("channellayout"), QString::number(channel_layout_));
|
|
||||||
writer->writeTextElement(QStringLiteral("format"), QString::number(format_));
|
|
||||||
writer->writeTextElement(QStringLiteral("enabled"), QString::number(enabled_));
|
|
||||||
writer->writeTextElement(QStringLiteral("streamindex"), QString::number(stream_index_));
|
|
||||||
writer->writeTextElement(QStringLiteral("duration"), QString::number(duration_));
|
|
||||||
writer->writeTextElement(QStringLiteral("timebase"), QString::fromStdString(timebase_.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AudioParams::SampleRateToString(const int &sample_rate)
|
|
||||||
{
|
|
||||||
return QCoreApplication::translate("AudioParams", "%1 Hz").arg(sample_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AudioParams::ChannelLayoutToString(const uint64_t &layout)
|
|
||||||
{
|
|
||||||
switch (layout) {
|
|
||||||
case AV_CH_LAYOUT_MONO:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Mono");
|
|
||||||
case AV_CH_LAYOUT_STEREO:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Stereo");
|
|
||||||
case AV_CH_LAYOUT_2_1:
|
|
||||||
return QCoreApplication::translate("AudioParams", "2.1");
|
|
||||||
case AV_CH_LAYOUT_5POINT1:
|
|
||||||
return QCoreApplication::translate("AudioParams", "5.1");
|
|
||||||
case AV_CH_LAYOUT_7POINT1:
|
|
||||||
return QCoreApplication::translate("AudioParams", "7.1");
|
|
||||||
default:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Unknown (0x%1)").arg(layout, 1, 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AudioParams::FormatToString(const Format &f)
|
|
||||||
{
|
|
||||||
switch (f) {
|
|
||||||
case kFormatUnsigned8Packed:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Unsigned 8-bit (Packed)");
|
|
||||||
case kFormatSigned16Packed:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Signed 16-bit (Packed)");
|
|
||||||
case kFormatSigned32Packed:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Signed 32-bit (Packed)");
|
|
||||||
case kFormatSigned64Packed:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Signed 64-bit (Packed)");
|
|
||||||
case kFormatFloat32Packed:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Float 32-bit (Packed)");
|
|
||||||
case kFormatFloat64Packed:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Float 64-bit (Packed)");
|
|
||||||
case kFormatUnsigned8Planar:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Unsigned 8-bit (Planar)");
|
|
||||||
case kFormatSigned16Planar:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Signed 16-bit (Planar)");
|
|
||||||
case kFormatSigned32Planar:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Signed 32-bit (Planar)");
|
|
||||||
case kFormatSigned64Planar:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Signed 64-bit (Planar)");
|
|
||||||
case kFormatFloat32Planar:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Float 32-bit (Planar)");
|
|
||||||
case kFormatFloat64Planar:
|
|
||||||
return QCoreApplication::translate("AudioParams", "Float 64-bit (Planar)");
|
|
||||||
|
|
||||||
case kFormatInvalid:
|
|
||||||
case kFormatCount:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QCoreApplication::translate("AudioParams", "Unknown (0x%1)").arg(f, 1, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioParams::Format AudioParams::GetPackedEquivalent(Format fmt)
|
|
||||||
{
|
|
||||||
switch (fmt) {
|
|
||||||
|
|
||||||
// For packed input, just return input
|
|
||||||
case kFormatUnsigned8Packed:
|
|
||||||
case kFormatSigned16Packed:
|
|
||||||
case kFormatSigned32Packed:
|
|
||||||
case kFormatSigned64Packed:
|
|
||||||
case kFormatFloat32Packed:
|
|
||||||
case kFormatFloat64Packed:
|
|
||||||
return fmt;
|
|
||||||
|
|
||||||
// Convert to packed
|
|
||||||
case kFormatUnsigned8Planar:
|
|
||||||
return kFormatUnsigned8Packed;
|
|
||||||
case kFormatSigned16Planar:
|
|
||||||
return kFormatSigned16Packed;
|
|
||||||
case kFormatSigned32Planar:
|
|
||||||
return kFormatSigned32Packed;
|
|
||||||
case kFormatSigned64Planar:
|
|
||||||
return kFormatSigned64Packed;
|
|
||||||
case kFormatFloat32Planar:
|
|
||||||
return kFormatFloat32Packed;
|
|
||||||
case kFormatFloat64Planar:
|
|
||||||
return kFormatFloat64Packed;
|
|
||||||
|
|
||||||
case kFormatInvalid:
|
|
||||||
case kFormatCount:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kFormatInvalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioParams::Format AudioParams::GetPlanarEquivalent(Format fmt)
|
|
||||||
{
|
|
||||||
switch (fmt) {
|
|
||||||
|
|
||||||
// Convert to planar
|
|
||||||
case kFormatUnsigned8Packed:
|
|
||||||
return kFormatUnsigned8Planar;
|
|
||||||
case kFormatSigned16Packed:
|
|
||||||
return kFormatSigned16Planar;
|
|
||||||
case kFormatSigned32Packed:
|
|
||||||
return kFormatSigned32Planar;
|
|
||||||
case kFormatSigned64Packed:
|
|
||||||
return kFormatSigned64Planar;
|
|
||||||
case kFormatFloat32Packed:
|
|
||||||
return kFormatFloat32Planar;
|
|
||||||
case kFormatFloat64Packed:
|
|
||||||
return kFormatFloat64Planar;
|
|
||||||
|
|
||||||
// For planar input, just return input
|
|
||||||
case kFormatUnsigned8Planar:
|
|
||||||
case kFormatSigned16Planar:
|
|
||||||
case kFormatSigned32Planar:
|
|
||||||
case kFormatSigned64Planar:
|
|
||||||
case kFormatFloat32Planar:
|
|
||||||
case kFormatFloat64Planar:
|
|
||||||
return fmt;
|
|
||||||
|
|
||||||
case kFormatInvalid:
|
|
||||||
case kFormatCount:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kFormatInvalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioParams::calculate_channel_count()
|
|
||||||
{
|
|
||||||
channel_count_ = av_get_channel_layout_nb_channels(channel_layout());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,282 +0,0 @@
|
|||||||
/***
|
|
||||||
|
|
||||||
Olive - Non-Linear Video Editor
|
|
||||||
Copyright (C) 2022 Olive Team
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef AUDIOPARAMS_H
|
|
||||||
#define AUDIOPARAMS_H
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <libavutil/channel_layout.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <olive/core/core.h>
|
|
||||||
#include <QtMath>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
#include <QXmlStreamWriter>
|
|
||||||
|
|
||||||
namespace olive {
|
|
||||||
|
|
||||||
using namespace core;
|
|
||||||
|
|
||||||
class AudioParams {
|
|
||||||
public:
|
|
||||||
// Only append to this list (never insert) because indexes are used in serialized files
|
|
||||||
enum Format {
|
|
||||||
/// Invalid
|
|
||||||
kFormatInvalid = -1,
|
|
||||||
|
|
||||||
/// 8-bit unsigned integer
|
|
||||||
kFormatUnsigned8Planar,
|
|
||||||
|
|
||||||
/// 16-bit signed integer
|
|
||||||
kFormatSigned16Planar,
|
|
||||||
|
|
||||||
/// 32-bit signed integer
|
|
||||||
kFormatSigned32Planar,
|
|
||||||
|
|
||||||
/// 64-bit signed integer
|
|
||||||
kFormatSigned64Planar,
|
|
||||||
|
|
||||||
/// 32-bit float
|
|
||||||
kFormatFloat32Planar,
|
|
||||||
|
|
||||||
/// 64-bit float
|
|
||||||
kFormatFloat64Planar,
|
|
||||||
|
|
||||||
/// 8-bit unsigned integer
|
|
||||||
kFormatUnsigned8Packed,
|
|
||||||
|
|
||||||
/// 16-bit signed integer
|
|
||||||
kFormatSigned16Packed,
|
|
||||||
|
|
||||||
/// 32-bit signed integer
|
|
||||||
kFormatSigned32Packed,
|
|
||||||
|
|
||||||
/// 64-bit signed integer
|
|
||||||
kFormatSigned64Packed,
|
|
||||||
|
|
||||||
/// 32-bit float
|
|
||||||
kFormatFloat32Packed,
|
|
||||||
|
|
||||||
/// 64-bit float
|
|
||||||
kFormatFloat64Packed,
|
|
||||||
|
|
||||||
/// Total format count
|
|
||||||
kFormatCount,
|
|
||||||
|
|
||||||
kPlanarStart = kFormatUnsigned8Planar,
|
|
||||||
kPackedStart = kFormatUnsigned8Packed,
|
|
||||||
kPlanarEnd = kPackedStart,
|
|
||||||
kPackedEnd = kFormatCount
|
|
||||||
};
|
|
||||||
|
|
||||||
static const Format kInternalFormat;
|
|
||||||
|
|
||||||
AudioParams() :
|
|
||||||
sample_rate_(0),
|
|
||||||
channel_layout_(0),
|
|
||||||
format_(kFormatInvalid)
|
|
||||||
{
|
|
||||||
set_default_footage_parameters();
|
|
||||||
|
|
||||||
// Cache channel count
|
|
||||||
calculate_channel_count();
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioParams(const int& sample_rate, const uint64_t& channel_layout, const Format& format) :
|
|
||||||
sample_rate_(sample_rate),
|
|
||||||
channel_layout_(channel_layout),
|
|
||||||
format_(format)
|
|
||||||
{
|
|
||||||
set_default_footage_parameters();
|
|
||||||
timebase_ = sample_rate_as_time_base();
|
|
||||||
|
|
||||||
// Cache channel count
|
|
||||||
calculate_channel_count();
|
|
||||||
}
|
|
||||||
|
|
||||||
int sample_rate() const
|
|
||||||
{
|
|
||||||
return sample_rate_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_sample_rate(int sample_rate)
|
|
||||||
{
|
|
||||||
sample_rate_ = sample_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t channel_layout() const
|
|
||||||
{
|
|
||||||
return channel_layout_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_channel_layout(uint64_t channel_layout)
|
|
||||||
{
|
|
||||||
channel_layout_ = channel_layout;
|
|
||||||
calculate_channel_count();
|
|
||||||
}
|
|
||||||
|
|
||||||
rational time_base() const
|
|
||||||
{
|
|
||||||
return timebase_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_time_base(const rational& timebase)
|
|
||||||
{
|
|
||||||
timebase_ = timebase;
|
|
||||||
}
|
|
||||||
|
|
||||||
rational sample_rate_as_time_base() const
|
|
||||||
{
|
|
||||||
return rational(1, sample_rate());
|
|
||||||
}
|
|
||||||
|
|
||||||
Format format() const
|
|
||||||
{
|
|
||||||
return format_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_format(Format format)
|
|
||||||
{
|
|
||||||
format_ = format;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool enabled() const
|
|
||||||
{
|
|
||||||
return enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_enabled(bool e)
|
|
||||||
{
|
|
||||||
enabled_ = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
int stream_index() const
|
|
||||||
{
|
|
||||||
return stream_index_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_stream_index(int s)
|
|
||||||
{
|
|
||||||
stream_index_ = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t duration() const
|
|
||||||
{
|
|
||||||
return duration_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_duration(int64_t duration)
|
|
||||||
{
|
|
||||||
duration_ = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool FormatIsPacked(Format f)
|
|
||||||
{
|
|
||||||
return f >= kPackedStart && f < kPackedEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FormatIsPacked() const
|
|
||||||
{
|
|
||||||
return FormatIsPacked(format_);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool FormatIsPlanar(Format f)
|
|
||||||
{
|
|
||||||
return f >= kPlanarStart && f < kPlanarEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FormatIsPlanar() const
|
|
||||||
{
|
|
||||||
return FormatIsPlanar(format_);
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 time_to_bytes(const double& time) const;
|
|
||||||
qint64 time_to_bytes(const rational& time) const;
|
|
||||||
qint64 time_to_bytes_per_channel(const double& time) const;
|
|
||||||
qint64 time_to_bytes_per_channel(const rational& time) const;
|
|
||||||
qint64 time_to_samples(const double& time) const;
|
|
||||||
qint64 time_to_samples(const rational& time) const;
|
|
||||||
qint64 samples_to_bytes(const qint64& samples) const;
|
|
||||||
qint64 samples_to_bytes_per_channel(const qint64& samples) const;
|
|
||||||
rational samples_to_time(const qint64& samples) const;
|
|
||||||
qint64 bytes_to_samples(const qint64 &bytes) const;
|
|
||||||
rational bytes_to_time(const qint64 &bytes) const;
|
|
||||||
rational bytes_per_channel_to_time(const qint64 &bytes) const;
|
|
||||||
int channel_count() const;
|
|
||||||
int bytes_per_sample_per_channel() const;
|
|
||||||
int bits_per_sample() const;
|
|
||||||
bool is_valid() const;
|
|
||||||
|
|
||||||
void Load(QXmlStreamReader* reader);
|
|
||||||
|
|
||||||
void Save(QXmlStreamWriter* writer) const;
|
|
||||||
|
|
||||||
bool operator==(const AudioParams& other) const;
|
|
||||||
bool operator!=(const AudioParams& other) const;
|
|
||||||
|
|
||||||
static const QVector<uint64_t> kSupportedChannelLayouts;
|
|
||||||
static const QVector<int> kSupportedSampleRates;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert integer sample rate to a user-friendly string
|
|
||||||
*/
|
|
||||||
static QString SampleRateToString(const int &sample_rate);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert channel layout to a user-friendly string
|
|
||||||
*/
|
|
||||||
static QString ChannelLayoutToString(const uint64_t &layout);
|
|
||||||
|
|
||||||
static QString FormatToString(const Format &f);
|
|
||||||
|
|
||||||
static AudioParams::Format GetPackedEquivalent(AudioParams::Format fmt);
|
|
||||||
static AudioParams::Format GetPlanarEquivalent(AudioParams::Format fmt);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void set_default_footage_parameters()
|
|
||||||
{
|
|
||||||
enabled_ = true;
|
|
||||||
stream_index_ = 0;
|
|
||||||
duration_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void calculate_channel_count();
|
|
||||||
|
|
||||||
int sample_rate_;
|
|
||||||
|
|
||||||
uint64_t channel_layout_;
|
|
||||||
|
|
||||||
int channel_count_;
|
|
||||||
|
|
||||||
Format format_;
|
|
||||||
|
|
||||||
// Footage-specific
|
|
||||||
int enabled_; // Switching this to int fixes GCC 11 stringop-overflow issue, I guess a byte-alignment issue?
|
|
||||||
int stream_index_;
|
|
||||||
int64_t duration_;
|
|
||||||
rational timebase_;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(olive::AudioParams)
|
|
||||||
|
|
||||||
#endif // AUDIOPARAMS_H
|
|
||||||
@@ -68,28 +68,28 @@ void AudioPlaybackCache::WriteSilence(const TimeRange &range)
|
|||||||
|
|
||||||
bool AudioPlaybackCache::WritePartOfSampleBuffer(const SampleBuffer &samples, const rational &write_start, const rational &buffer_start, const rational &length)
|
bool AudioPlaybackCache::WritePartOfSampleBuffer(const SampleBuffer &samples, const rational &write_start, const rational &buffer_start, const rational &length)
|
||||||
{
|
{
|
||||||
qint64 length_in_bytes = params_.time_to_bytes_per_channel(length);
|
int64_t length_in_bytes = params_.time_to_bytes_per_channel(length);
|
||||||
|
|
||||||
qint64 start_cache_offset = params_.time_to_bytes_per_channel(write_start);
|
int64_t start_cache_offset = params_.time_to_bytes_per_channel(write_start);
|
||||||
qint64 end_cache_offset = start_cache_offset + length_in_bytes;
|
int64_t end_cache_offset = start_cache_offset + length_in_bytes;
|
||||||
|
|
||||||
qint64 start_buffer_offset = params_.time_to_bytes_per_channel(buffer_start);
|
int64_t start_buffer_offset = params_.time_to_bytes_per_channel(buffer_start);
|
||||||
qint64 end_buffer_offset = std::min(start_buffer_offset + length_in_bytes, params_.samples_to_bytes_per_channel(samples.sample_count()));
|
int64_t end_buffer_offset = std::min(start_buffer_offset + length_in_bytes, params_.samples_to_bytes_per_channel(samples.sample_count()));
|
||||||
|
|
||||||
qint64 current_cache_offset = start_cache_offset;
|
int64_t current_cache_offset = start_cache_offset;
|
||||||
qint64 current_buffer_offset = start_buffer_offset;
|
int64_t current_buffer_offset = start_buffer_offset;
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
while (current_cache_offset != end_cache_offset) {
|
while (current_cache_offset != end_cache_offset) {
|
||||||
qint64 segment = current_cache_offset / kDefaultSegmentSizePerChannel;
|
int64_t segment = current_cache_offset / kDefaultSegmentSizePerChannel;
|
||||||
qint64 segment_start = segment * kDefaultSegmentSizePerChannel;
|
int64_t segment_start = segment * kDefaultSegmentSizePerChannel;
|
||||||
qint64 segment_end = segment_start + kDefaultSegmentSizePerChannel;
|
int64_t segment_end = segment_start + kDefaultSegmentSizePerChannel;
|
||||||
|
|
||||||
qint64 offset_in_segment = current_cache_offset - segment_start;
|
int64_t offset_in_segment = current_cache_offset - segment_start;
|
||||||
qint64 write_len = segment_end - offset_in_segment;
|
int64_t write_len = segment_end - offset_in_segment;
|
||||||
qint64 max_buffer_len = end_buffer_offset - current_buffer_offset;
|
int64_t max_buffer_len = end_buffer_offset - current_buffer_offset;
|
||||||
qint64 zero_len = 0;
|
int64_t zero_len = 0;
|
||||||
|
|
||||||
if (write_len > max_buffer_len) {
|
if (write_len > max_buffer_len) {
|
||||||
zero_len = write_len - max_buffer_len;
|
zero_len = write_len - max_buffer_len;
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#define AUDIOPLAYBACKCACHE_H
|
#define AUDIOPLAYBACKCACHE_H
|
||||||
|
|
||||||
#include "audio/audiovisualwaveform.h"
|
#include "audio/audiovisualwaveform.h"
|
||||||
#include "codec/samplebuffer.h"
|
|
||||||
#include "render/playbackcache.h"
|
#include "render/playbackcache.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ bool FrameHashCache::SaveCacheFrame(const QString &filename, const FramePtr fram
|
|||||||
break;
|
break;
|
||||||
case PixelFormat::F16:
|
case PixelFormat::F16:
|
||||||
case PixelFormat::F32:
|
case PixelFormat::F32:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#define SAMPLEJOB_H
|
#define SAMPLEJOB_H
|
||||||
|
|
||||||
#include "acceleratedjob.h"
|
#include "acceleratedjob.h"
|
||||||
#include "codec/samplebuffer.h"
|
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
|||||||
@@ -725,7 +725,7 @@ GLint OpenGLRenderer::GetInternalFormat(PixelFormat format, int channel_layout)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,7 +745,7 @@ GLenum OpenGLRenderer::GetPixelType(PixelFormat format)
|
|||||||
return GL_FLOAT;
|
return GL_FLOAT;
|
||||||
|
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
#include "node/node.h"
|
#include "node/node.h"
|
||||||
#include "node/output/viewer/viewer.h"
|
#include "node/output/viewer/viewer.h"
|
||||||
#include "node/project/project.h"
|
#include "node/project/project.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/projectcopier.h"
|
#include "render/projectcopier.h"
|
||||||
#include "render/renderjobtracker.h"
|
#include "render/renderjobtracker.h"
|
||||||
#include "render/rendermanager.h"
|
#include "render/rendermanager.h"
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
|
|
||||||
#include "codec/frame.h"
|
#include "codec/frame.h"
|
||||||
#include "codec/samplebuffer.h"
|
|
||||||
#include "common/cancelableobject.h"
|
#include "common/cancelableobject.h"
|
||||||
#include "node/output/viewer/viewer.h"
|
#include "node/output/viewer/viewer.h"
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ int VideoParams::GetBytesPerChannel(PixelFormat format)
|
|||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
case PixelFormat::U8:
|
case PixelFormat::U8:
|
||||||
return 1;
|
return 1;
|
||||||
@@ -222,7 +222,7 @@ QString VideoParams::GetFormatName(PixelFormat format)
|
|||||||
case PixelFormat::F32:
|
case PixelFormat::F32:
|
||||||
return QCoreApplication::translate("VideoParams", "Full-Float (32-bit)");
|
return QCoreApplication::translate("VideoParams", "Full-Float (32-bit)");
|
||||||
case PixelFormat::INVALID:
|
case PixelFormat::INVALID:
|
||||||
case PixelFormat::FORMAT_COUNT:
|
case PixelFormat::COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ bool VideoParams::is_valid() const
|
|||||||
return (width() > 0
|
return (width() > 0
|
||||||
&& height() > 0
|
&& height() > 0
|
||||||
&& !pixel_aspect_ratio_.isNull()
|
&& !pixel_aspect_ratio_.isNull()
|
||||||
&& format_ > PixelFormat::INVALID && format_ < PixelFormat::FORMAT_COUNT
|
&& format_ > PixelFormat::INVALID && format_ < PixelFormat::COUNT
|
||||||
&& channel_count_ > 0);
|
&& channel_count_ > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include "codec/decoder.h"
|
#include "codec/decoder.h"
|
||||||
#include "node/project/footage/footage.h"
|
#include "node/project/footage/footage.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "task/task.h"
|
#include "task/task.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|||||||
@@ -28,5 +28,7 @@ set(OLIVE_SOURCES
|
|||||||
${OLIVE_SOURCES}
|
${OLIVE_SOURCES}
|
||||||
ui/colorcoding.cpp
|
ui/colorcoding.cpp
|
||||||
ui/colorcoding.h
|
ui/colorcoding.h
|
||||||
|
ui/humanstrings.cpp
|
||||||
|
ui/humanstrings.h
|
||||||
PARENT_SCOPE
|
PARENT_SCOPE
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include "humanstrings.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
namespace olive {
|
||||||
|
|
||||||
|
QString HumanStrings::SampleRateToString(const int &sample_rate)
|
||||||
|
{
|
||||||
|
return QCoreApplication::translate("AudioParams", "%1 Hz").arg(sample_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HumanStrings::ChannelLayoutToString(const uint64_t &layout)
|
||||||
|
{
|
||||||
|
switch (layout) {
|
||||||
|
case AV_CH_LAYOUT_MONO:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Mono");
|
||||||
|
case AV_CH_LAYOUT_STEREO:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Stereo");
|
||||||
|
case AV_CH_LAYOUT_2_1:
|
||||||
|
return QCoreApplication::translate("AudioParams", "2.1");
|
||||||
|
case AV_CH_LAYOUT_5POINT1:
|
||||||
|
return QCoreApplication::translate("AudioParams", "5.1");
|
||||||
|
case AV_CH_LAYOUT_7POINT1:
|
||||||
|
return QCoreApplication::translate("AudioParams", "7.1");
|
||||||
|
default:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Unknown (0x%1)").arg(layout, 1, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HumanStrings::FormatToString(const SampleFormat &f)
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case SampleFormat::U8:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Unsigned 8-bit (Packed)");
|
||||||
|
case SampleFormat::S16:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Signed 16-bit (Packed)");
|
||||||
|
case SampleFormat::S32:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Signed 32-bit (Packed)");
|
||||||
|
case SampleFormat::S64:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Signed 64-bit (Packed)");
|
||||||
|
case SampleFormat::F32:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Float 32-bit (Packed)");
|
||||||
|
case SampleFormat::F64:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Float 64-bit (Packed)");
|
||||||
|
case SampleFormat::U8P:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Unsigned 8-bit (Planar)");
|
||||||
|
case SampleFormat::S16P:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Signed 16-bit (Planar)");
|
||||||
|
case SampleFormat::S32P:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Signed 32-bit (Planar)");
|
||||||
|
case SampleFormat::S64P:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Signed 64-bit (Planar)");
|
||||||
|
case SampleFormat::F32P:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Float 32-bit (Planar)");
|
||||||
|
case SampleFormat::F64P:
|
||||||
|
return QCoreApplication::translate("AudioParams", "Float 64-bit (Planar)");
|
||||||
|
|
||||||
|
case SampleFormat::INVALID:
|
||||||
|
case SampleFormat::COUNT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QCoreApplication::translate("AudioParams", "Unknown (0x%1)").arg(f, 1, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef HUMANSTRINGS_H
|
||||||
|
#define HUMANSTRINGS_H
|
||||||
|
|
||||||
|
#include <olive/core/core.h>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
|
class HumanStrings : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
HumanStrings() = default;
|
||||||
|
|
||||||
|
static QString SampleRateToString(const int &sample_rate);
|
||||||
|
|
||||||
|
static QString ChannelLayoutToString(const uint64_t &layout);
|
||||||
|
|
||||||
|
static QString FormatToString(const SampleFormat &f);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HUMANSTRINGS_H
|
||||||
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "audio/audiovisualwaveform.h"
|
#include "audio/audiovisualwaveform.h"
|
||||||
#include "common/define.h"
|
#include "common/define.h"
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/audiowaveformcache.h"
|
#include "render/audiowaveformcache.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|||||||
@@ -21,14 +21,16 @@
|
|||||||
#ifndef BEZIERWIDGET_H
|
#ifndef BEZIERWIDGET_H
|
||||||
#define BEZIERWIDGET_H
|
#define BEZIERWIDGET_H
|
||||||
|
|
||||||
|
#include <olive/core/core.h>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "common/bezier.h"
|
|
||||||
#include "widget/slider/floatslider.h"
|
#include "widget/slider/floatslider.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
class BezierWidget : public QWidget
|
class BezierWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
#include "common/clamp.h"
|
|
||||||
#include "common/lerp.h"
|
#include "common/lerp.h"
|
||||||
#include "node/node.h"
|
#include "node/node.h"
|
||||||
|
|
||||||
@@ -76,7 +75,7 @@ void ColorGradientWidget::paintEvent(QPaintEvent *e)
|
|||||||
p.setPen(QPen(GetUISelectorColor(), qMax(1, selector_radius / 2)));
|
p.setPen(QPen(GetUISelectorColor(), qMax(1, selector_radius / 2)));
|
||||||
p.setBrush(Qt::NoBrush);
|
p.setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
float clamped_val = clamp(val_, 0.0f, 1.0f);
|
float clamped_val = std::clamp(val_, 0.0f, 1.0f);
|
||||||
|
|
||||||
if (orientation_ == Qt::Horizontal) {
|
if (orientation_ == Qt::Horizontal) {
|
||||||
p.drawRect(qRound(width() * (1.0 - clamped_val)) - selector_radius, 0, selector_radius * 2, height() - 1);
|
p.drawRect(qRound(width() * (1.0 - clamped_val)) - selector_radius, 0, selector_radius * 2, height() - 1);
|
||||||
@@ -99,7 +98,7 @@ void ColorGradientWidget::SelectedColorChangedEvent(const Color &c, bool externa
|
|||||||
|
|
||||||
Color ColorGradientWidget::LerpColor(const Color &a, const Color &b, int i, int max)
|
Color ColorGradientWidget::LerpColor(const Color &a, const Color &b, int i, int max)
|
||||||
{
|
{
|
||||||
float t = clamp(static_cast<float>(i) / static_cast<float>(max), 0.0f, 1.0f);
|
float t = std::clamp(static_cast<float>(i) / static_cast<float>(max), 0.0f, 1.0f);
|
||||||
|
|
||||||
return Color(lerp(a.red(), b.red(), t),
|
return Color(lerp(a.red(), b.red(), t),
|
||||||
lerp(a.green(), b.green(), t),
|
lerp(a.green(), b.green(), t),
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
|
||||||
#include "common/clamp.h"
|
|
||||||
#include "node/node.h"
|
#include "node/node.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
@@ -121,7 +120,7 @@ void ColorWheelWidget::SelectedColorChangedEvent(const Color &c, bool external)
|
|||||||
{
|
{
|
||||||
if (external) {
|
if (external) {
|
||||||
force_redraw_ = true;
|
force_redraw_ = true;
|
||||||
val_ = clamp(c.value(), 0.0f, 1.0f);
|
val_ = std::clamp(c.value(), 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include <QStyleOptionGraphicsItem>
|
#include <QStyleOptionGraphicsItem>
|
||||||
|
|
||||||
#include "common/bezier.h"
|
|
||||||
#include "common/lerp.h"
|
#include "common/lerp.h"
|
||||||
#include "nodeview.h"
|
#include "nodeview.h"
|
||||||
#include "nodeviewitem.h"
|
#include "nodeviewitem.h"
|
||||||
@@ -183,7 +182,7 @@ void NodeViewEdge::UpdateCurve()
|
|||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
path.moveTo(start);
|
path.moveTo(start);
|
||||||
|
|
||||||
double angle = qAtan2(end.y() - start.y(), end.x() - start.x());
|
double angle = std::atan2(end.y() - start.y(), end.x() - start.x());
|
||||||
|
|
||||||
if (curved_) {
|
if (curved_) {
|
||||||
|
|
||||||
@@ -220,7 +219,7 @@ void NodeViewEdge::UpdateCurve()
|
|||||||
path.cubicTo(cp1, cp2, end);
|
path.cubicTo(cp1, cp2, end);
|
||||||
|
|
||||||
if (!qFuzzyCompare(start.x(), end.x())) {
|
if (!qFuzzyCompare(start.x(), end.x())) {
|
||||||
double continue_x = end.x() - qCos(angle);
|
double continue_x = end.x() - std::cos(angle);
|
||||||
|
|
||||||
double x1 = start.x();
|
double x1 = start.x();
|
||||||
double x2 = cp1.x();
|
double x2 = cp1.x();
|
||||||
@@ -241,7 +240,7 @@ void NodeViewEdge::UpdateCurve()
|
|||||||
double t = Bezier::CubicXtoT(continue_x, x1, x2, x3, x4);
|
double t = Bezier::CubicXtoT(continue_x, x1, x2, x3, x4);
|
||||||
double y = Bezier::CubicTtoY(y1, y2, y3, y4, t);
|
double y = Bezier::CubicTtoY(y1, y2, y3, y4, t);
|
||||||
|
|
||||||
angle = qAtan2(end.y() - y, end.x() - continue_x);
|
angle = std::atan2(end.y() - y, end.x() - continue_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common/clamp.h"
|
|
||||||
#include "common/lerp.h"
|
#include "common/lerp.h"
|
||||||
#include "common/qtutils.h"
|
#include "common/qtutils.h"
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
|
|||||||
@@ -21,12 +21,15 @@
|
|||||||
#ifndef CHANNELLAYOUTCOMBOBOX_H
|
#ifndef CHANNELLAYOUTCOMBOBOX_H
|
||||||
#define CHANNELLAYOUTCOMBOBOX_H
|
#define CHANNELLAYOUTCOMBOBOX_H
|
||||||
|
|
||||||
|
#include <olive/core/core.h>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
|
||||||
#include "render/audioparams.h"
|
#include "ui/humanstrings.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
class ChannelLayoutComboBox : public QComboBox
|
class ChannelLayoutComboBox : public QComboBox
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -35,7 +38,7 @@ public:
|
|||||||
QComboBox(parent)
|
QComboBox(parent)
|
||||||
{
|
{
|
||||||
foreach (const uint64_t& ch_layout, AudioParams::kSupportedChannelLayouts) {
|
foreach (const uint64_t& ch_layout, AudioParams::kSupportedChannelLayouts) {
|
||||||
this->addItem(AudioParams::ChannelLayoutToString(ch_layout),
|
this->addItem(HumanStrings::ChannelLayoutToString(ch_layout),
|
||||||
QVariant::fromValue(ch_layout));
|
QVariant::fromValue(ch_layout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
QComboBox(parent)
|
QComboBox(parent)
|
||||||
{
|
{
|
||||||
// Set up preview formats
|
// Set up preview formats
|
||||||
for (int i=0;i<PixelFormat::FORMAT_COUNT;i++) {
|
for (int i=0;i<PixelFormat::COUNT;i++) {
|
||||||
PixelFormat pix_fmt = static_cast<PixelFormat::Format>(i);
|
PixelFormat pix_fmt = static_cast<PixelFormat::Format>(i);
|
||||||
|
|
||||||
if (!float_only || pix_fmt.is_float()) {
|
if (!float_only || pix_fmt.is_float()) {
|
||||||
|
|||||||
@@ -21,12 +21,15 @@
|
|||||||
#ifndef SAMPLEFORMATCOMBOBOX_H
|
#ifndef SAMPLEFORMATCOMBOBOX_H
|
||||||
#define SAMPLEFORMATCOMBOBOX_H
|
#define SAMPLEFORMATCOMBOBOX_H
|
||||||
|
|
||||||
|
#include <olive/core/core.h>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
|
||||||
#include "render/audioparams.h"
|
#include "ui/humanstrings.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
class SampleFormatComboBox : public QComboBox
|
class SampleFormatComboBox : public QComboBox
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -39,16 +42,16 @@ public:
|
|||||||
|
|
||||||
void SetAttemptToRestoreFormat(bool e) { attempt_to_restore_format_ = e; }
|
void SetAttemptToRestoreFormat(bool e) { attempt_to_restore_format_ = e; }
|
||||||
|
|
||||||
void SetAvailableFormats(const std::vector<AudioParams::Format> &formats)
|
void SetAvailableFormats(const std::vector<SampleFormat> &formats)
|
||||||
{
|
{
|
||||||
AudioParams::Format tmp = AudioParams::kFormatInvalid;
|
SampleFormat tmp = SampleFormat::INVALID;
|
||||||
|
|
||||||
if (attempt_to_restore_format_) {
|
if (attempt_to_restore_format_) {
|
||||||
tmp = GetSampleFormat();
|
tmp = GetSampleFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
foreach (const AudioParams::Format &of, formats) {
|
foreach (const SampleFormat &of, formats) {
|
||||||
AddFormatItem(of);
|
AddFormatItem(of);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,15 +62,15 @@ public:
|
|||||||
|
|
||||||
void SetPackedFormats()
|
void SetPackedFormats()
|
||||||
{
|
{
|
||||||
AudioParams::Format tmp = AudioParams::kFormatInvalid;
|
SampleFormat tmp = SampleFormat::INVALID;
|
||||||
|
|
||||||
if (attempt_to_restore_format_) {
|
if (attempt_to_restore_format_) {
|
||||||
tmp = GetSampleFormat();
|
tmp = GetSampleFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
for (int i=AudioParams::kPackedStart; i<AudioParams::kPackedEnd; i++) {
|
for (int i=SampleFormat::PACKED_START; i<SampleFormat::PACKED_END; i++) {
|
||||||
AddFormatItem(static_cast<AudioParams::Format>(i));
|
AddFormatItem(static_cast<SampleFormat::Format>(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attempt_to_restore_format_) {
|
if (attempt_to_restore_format_) {
|
||||||
@@ -75,12 +78,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioParams::Format GetSampleFormat() const
|
SampleFormat GetSampleFormat() const
|
||||||
{
|
{
|
||||||
return static_cast<AudioParams::Format>(this->currentData().toInt());
|
return static_cast<SampleFormat::Format>(this->currentData().toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSampleFormat(AudioParams::Format fmt)
|
void SetSampleFormat(SampleFormat fmt)
|
||||||
{
|
{
|
||||||
for (int i=0; i<this->count(); i++) {
|
for (int i=0; i<this->count(); i++) {
|
||||||
if (this->itemData(i).toInt() == fmt) {
|
if (this->itemData(i).toInt() == fmt) {
|
||||||
@@ -91,9 +94,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AddFormatItem(AudioParams::Format f)
|
void AddFormatItem(SampleFormat f)
|
||||||
{
|
{
|
||||||
this->addItem(AudioParams::FormatToString(f), f);
|
this->addItem(HumanStrings::FormatToString(f), static_cast<SampleFormat::Format>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attempt_to_restore_format_;
|
bool attempt_to_restore_format_;
|
||||||
|
|||||||
@@ -21,12 +21,15 @@
|
|||||||
#ifndef SAMPLERATECOMBOBOX_H
|
#ifndef SAMPLERATECOMBOBOX_H
|
||||||
#define SAMPLERATECOMBOBOX_H
|
#define SAMPLERATECOMBOBOX_H
|
||||||
|
|
||||||
|
#include <olive/core/core.h>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
|
||||||
#include "render/audioparams.h"
|
#include "ui/humanstrings.h"
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
class SampleRateComboBox : public QComboBox
|
class SampleRateComboBox : public QComboBox
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -35,7 +38,7 @@ public:
|
|||||||
QComboBox(parent)
|
QComboBox(parent)
|
||||||
{
|
{
|
||||||
foreach (int sr, AudioParams::kSupportedSampleRates) {
|
foreach (int sr, AudioParams::kSupportedSampleRates) {
|
||||||
this->addItem(AudioParams::SampleRateToString(sr), sr);
|
this->addItem(HumanStrings::SampleRateToString(sr), sr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ void TimeBasedWidget::UpdateMaximumScroll()
|
|||||||
rational length = (viewer_node_) ? viewer_node_->GetLength() : 0;
|
rational length = (viewer_node_) ? viewer_node_->GetLength() : 0;
|
||||||
|
|
||||||
if (auto_max_scrollbar_) {
|
if (auto_max_scrollbar_) {
|
||||||
scrollbar_->setMaximum(qMax(0, qCeil(TimeToScene(length)) - width()));
|
scrollbar_->setMaximum(std::max(0, int(std::ceil(TimeToScene(length)) - width())));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (TimeBasedView* base, timeline_views_) {
|
foreach (TimeBasedView* base, timeline_views_) {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
|
||||||
#include "audio/audiovisualwaveform.h"
|
#include "audio/audiovisualwaveform.h"
|
||||||
#include "common/clamp.h"
|
|
||||||
|
|
||||||
namespace olive {
|
namespace olive {
|
||||||
|
|
||||||
@@ -124,7 +123,7 @@ void TimeScaledObject::SetScale(const double& scale)
|
|||||||
{
|
{
|
||||||
Q_ASSERT(scale > 0);
|
Q_ASSERT(scale > 0);
|
||||||
|
|
||||||
scale_ = clamp(scale, min_scale_, max_scale_);
|
scale_ = std::clamp(scale, min_scale_, max_scale_);
|
||||||
|
|
||||||
ScaleChangedEvent(scale_);
|
ScaleChangedEvent(scale_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QToolTip>
|
#include <QToolTip>
|
||||||
|
|
||||||
#include "common/clamp.h"
|
|
||||||
#include "common/qtutils.h"
|
#include "common/qtutils.h"
|
||||||
#include "common/range.h"
|
#include "common/range.h"
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
@@ -948,7 +947,7 @@ rational PointerTool::ValidateInTrimming(rational movement)
|
|||||||
|
|
||||||
// Clamp adjusted value between the earliest and latest values
|
// Clamp adjusted value between the earliest and latest values
|
||||||
rational adjusted = ghost->GetIn() + movement;
|
rational adjusted = ghost->GetIn() + movement;
|
||||||
rational clamped = clamp(adjusted, earliest_in, latest_in);
|
rational clamped = std::clamp(adjusted, earliest_in, latest_in);
|
||||||
|
|
||||||
if (clamped != adjusted) {
|
if (clamped != adjusted) {
|
||||||
movement = clamped - ghost->GetIn();
|
movement = clamped - ghost->GetIn();
|
||||||
@@ -985,7 +984,7 @@ rational PointerTool::ValidateOutTrimming(rational movement)
|
|||||||
|
|
||||||
// Clamp adjusted value between the earliest and latest values
|
// Clamp adjusted value between the earliest and latest values
|
||||||
rational adjusted = ghost->GetOut() + movement;
|
rational adjusted = ghost->GetOut() + movement;
|
||||||
rational clamped = clamp(adjusted, earliest_out, latest_out);
|
rational clamped = std::clamp(adjusted, earliest_out, latest_out);
|
||||||
|
|
||||||
if (clamped != adjusted) {
|
if (clamped != adjusted) {
|
||||||
movement = clamped - ghost->GetOut();
|
movement = clamped - ghost->GetOut();
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ void TimeRuler::drawForeground(QPainter *p, const QRectF &rect)
|
|||||||
double screen_pt = static_cast<double>(i);
|
double screen_pt = static_cast<double>(i);
|
||||||
|
|
||||||
if (long_interval > -1) {
|
if (long_interval > -1) {
|
||||||
int this_long_unit = qFloor(screen_pt/long_interval);
|
int this_long_unit = std::floor(screen_pt/long_interval);
|
||||||
if (this_long_unit != last_long_unit) {
|
if (this_long_unit != last_long_unit) {
|
||||||
int line_y = long_y;
|
int line_y = long_y;
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ void TimeRuler::drawForeground(QPainter *p, const QRectF &rect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (short_interval > -1) {
|
if (short_interval > -1) {
|
||||||
int this_short_unit = qFloor(screen_pt/short_interval);
|
int this_short_unit = std::floor(screen_pt/short_interval);
|
||||||
if (this_short_unit != last_short_unit) {
|
if (this_short_unit != last_short_unit) {
|
||||||
p->drawLine(i, short_y, i, line_bottom);
|
p->drawLine(i, short_y, i, line_bottom);
|
||||||
last_short_unit = this_short_unit;
|
last_short_unit = this_short_unit;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
|
||||||
#include "common/clamp.h"
|
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
#include "timeline/timelinecommon.h"
|
#include "timeline/timelinecommon.h"
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <QtConcurrent/QtConcurrent>
|
#include <QtConcurrent/QtConcurrent>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "render/audioparams.h"
|
|
||||||
#include "render/audioplaybackcache.h"
|
#include "render/audioplaybackcache.h"
|
||||||
#include "widget/timeruler/seekablewidget.h"
|
#include "widget/timeruler/seekablewidget.h"
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#include "audio/audiomanager.h"
|
#include "audio/audiomanager.h"
|
||||||
#include "common/clamp.h"
|
|
||||||
#include "common/ratiodialog.h"
|
#include "common/ratiodialog.h"
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
@@ -512,7 +511,7 @@ void ViewerWidget::UpdateAudioProcessor()
|
|||||||
AudioParams ap = GetConnectedNode()->GetAudioParams();
|
AudioParams ap = GetConnectedNode()->GetAudioParams();
|
||||||
AudioParams packed(OLIVE_CONFIG("AudioOutputSampleRate").toInt(),
|
AudioParams packed(OLIVE_CONFIG("AudioOutputSampleRate").toInt(),
|
||||||
OLIVE_CONFIG("AudioOutputChannelLayout").toULongLong(),
|
OLIVE_CONFIG("AudioOutputChannelLayout").toULongLong(),
|
||||||
static_cast<AudioParams::Format>(OLIVE_CONFIG("AudioOutputSampleFormat").toInt()));
|
SampleFormat::from_string(OLIVE_CONFIG("AudioOutputSampleFormat").toString().toStdString()));
|
||||||
|
|
||||||
audio_processor_.Open(ap, packed, (playback_speed_ == 0) ? 1 : std::abs(playback_speed_));
|
audio_processor_.Open(ap, packed, (playback_speed_ == 0) ? 1 : std::abs(playback_speed_));
|
||||||
}
|
}
|
||||||
@@ -728,7 +727,7 @@ void ViewerWidget::QueueNextAudioBuffer()
|
|||||||
rational queue_end = audio_playback_queue_time_ + (kAudioPlaybackInterval * playback_speed_);
|
rational queue_end = audio_playback_queue_time_ + (kAudioPlaybackInterval * playback_speed_);
|
||||||
|
|
||||||
// Clamp queue end by zero and the audio length
|
// Clamp queue end by zero and the audio length
|
||||||
queue_end = clamp(queue_end, rational(0), GetConnectedNode()->GetAudioLength());
|
queue_end = std::clamp(queue_end, rational(0), GetConnectedNode()->GetAudioLength());
|
||||||
if ((playback_speed_ > 0 && queue_end <= audio_playback_queue_time_)
|
if ((playback_speed_ > 0 && queue_end <= audio_playback_queue_time_)
|
||||||
|| (playback_speed_ < 0 && queue_end >= audio_playback_queue_time_)) {
|
|| (playback_speed_ < 0 && queue_end >= audio_playback_queue_time_)) {
|
||||||
// This will queue nothing, so stop the loop here
|
// This will queue nothing, so stop the loop here
|
||||||
@@ -1558,7 +1557,9 @@ void ViewerWidget::Play(bool in_to_out_only)
|
|||||||
ExportFormat::GetExtension(static_cast<ExportFormat::Format>(OLIVE_CONFIG("AudioRecordingFormat").toInt())))
|
ExportFormat::GetExtension(static_cast<ExportFormat::Format>(OLIVE_CONFIG("AudioRecordingFormat").toInt())))
|
||||||
);
|
);
|
||||||
|
|
||||||
AudioParams ap(OLIVE_CONFIG("AudioRecordingSampleRate").toInt(), OLIVE_CONFIG("AudioRecordingChannelLayout").toULongLong(), static_cast<AudioParams::Format>(OLIVE_CONFIG("AudioRecordingSampleFormat").toInt()));
|
AudioParams ap(OLIVE_CONFIG("AudioRecordingSampleRate").toInt(),
|
||||||
|
OLIVE_CONFIG("AudioRecordingChannelLayout").toULongLong(),
|
||||||
|
SampleFormat::from_string(OLIVE_CONFIG("AudioRecordingSampleFormat").toString().toStdString()));
|
||||||
|
|
||||||
EncodingParams encode_param;
|
EncodingParams encode_param;
|
||||||
encode_param.EnableAudio(ap, static_cast<ExportCodec::Codec>(OLIVE_CONFIG("AudioRecordingCodec").toInt()));
|
encode_param.EnableAudio(ap, static_cast<ExportCodec::Codec>(OLIVE_CONFIG("AudioRecordingCodec").toInt()));
|
||||||
|
|||||||
@@ -29,15 +29,19 @@ foreach (COMPONENT ${LIBOLIVE_COMPONENTS})
|
|||||||
HINTS
|
HINTS
|
||||||
"${LIBOLIVE_LOCATION}"
|
"${LIBOLIVE_LOCATION}"
|
||||||
"$ENV{LIBOLIVE_LOCATION}"
|
"$ENV{LIBOLIVE_LOCATION}"
|
||||||
|
"${LIBOLIVE_ROOT}"
|
||||||
|
"$ENV{LIBOLIVE_ROOT}"
|
||||||
PATH_SUFFIXES
|
PATH_SUFFIXES
|
||||||
include/
|
include/
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(LIBOLIVE_${UPPER_COMPONENT}_LIBRARY
|
find_library(LIBOLIVE_${UPPER_COMPONENT}_LIBRARY
|
||||||
olivecore
|
olive${LOWER_COMPONENT}
|
||||||
HINTS
|
HINTS
|
||||||
"${LIBOLIVE_LOCATION}"
|
"${LIBOLIVE_LOCATION}"
|
||||||
"$ENV{LIBOLIVE_LOCATION}"
|
"$ENV{LIBOLIVE_LOCATION}"
|
||||||
|
"${LIBOLIVE_ROOT}"
|
||||||
|
"$ENV{LIBOLIVE_ROOT}"
|
||||||
PATH_SUFFIXES
|
PATH_SUFFIXES
|
||||||
lib/
|
lib/
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user