better waveforms
This commit is contained in:
@@ -48,7 +48,9 @@ void VolumeEffect::save(QXmlStreamWriter *stream) {
|
||||
void VolumeEffect::process_audio(quint8 *samples, int nb_bytes) {
|
||||
for (int i=0;i<nb_bytes;i+=2) {
|
||||
qint16 full_sample = (qint16) ((samples[i+1] << 8) | samples[i]);
|
||||
|
||||
full_sample *= volume_val->value()*0.01;
|
||||
|
||||
samples[i+1] = (quint8) (full_sample >> 8);
|
||||
samples[i] = (quint8) full_sample;
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ struct MediaStream {
|
||||
|
||||
// preview thumbnail/waveform
|
||||
bool preview_done;
|
||||
QImage preview;
|
||||
QImage preview; // TODO change to QPixmap
|
||||
QMutex preview_lock;
|
||||
int preview_audio_index;
|
||||
};
|
||||
|
||||
+20
-6
@@ -33,7 +33,7 @@ MediaStream* PreviewGenerator::get_stream_from_file_index(int index) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define WAVEFORM_RESOLUTION 256
|
||||
#define WAVEFORM_RESOLUTION 64
|
||||
|
||||
void PreviewGenerator::run() {
|
||||
if (media == NULL) {
|
||||
@@ -55,7 +55,9 @@ void PreviewGenerator::run() {
|
||||
if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
// initiate qimage
|
||||
MediaStream* ms = get_stream_from_file_index(i);
|
||||
ms->preview = QImage(fmt_ctx->streams[i]->duration * av_q2d(fmt_ctx->streams[i]->time_base) * WAVEFORM_RESOLUTION, 255, QImage::Format_RGBA8888);
|
||||
int width = fmt_ctx->streams[i]->duration * av_q2d(fmt_ctx->streams[i]->time_base) * WAVEFORM_RESOLUTION;
|
||||
if (width > 32767) qDebug() << "[WARNING] Due to limitations in Qt's painter, this waveform may not appear correctly (see issue #76)";
|
||||
ms->preview = QImage(width, 80, QImage::Format_RGBA8888);
|
||||
ms->preview_audio_index = 0;
|
||||
ms->preview.fill(Qt::transparent);
|
||||
}
|
||||
@@ -125,13 +127,25 @@ void PreviewGenerator::run() {
|
||||
QPainter p;
|
||||
p.begin(&s->preview);
|
||||
p.setPen(QColor(80, 80, 80));
|
||||
int channel_jump = swr_frame->channels * 2;
|
||||
int divider = (32768.0/(s->preview.height()/2))*swr_frame->channels;
|
||||
for (int i=0;i<swr_frame->nb_samples;i+=interval) {
|
||||
for (int j=0;j<swr_frame->channels;j++) {
|
||||
qint16 sample = ((swr_frame->data[0][i+1] << 8) | swr_frame->data[0][i]);
|
||||
sample /= 256;
|
||||
sample /= swr_frame->channels;
|
||||
qint16 min = 0;
|
||||
qint16 max = 0;
|
||||
for (int k=j*2;k<interval;k+=channel_jump) {
|
||||
qint16 sample = ((swr_frame->data[0][i+k+1] << 8) | swr_frame->data[0][i+k]);
|
||||
if (sample > max) {
|
||||
max = sample;
|
||||
} else if (sample < min) {
|
||||
min = sample;
|
||||
}
|
||||
}
|
||||
min /= divider;
|
||||
max /= divider;
|
||||
|
||||
int mid = channel_height*j+(channel_height/2);
|
||||
p.drawLine(s->preview_audio_index, mid, s->preview_audio_index, mid+sample);
|
||||
p.drawLine(s->preview_audio_index, mid+min, s->preview_audio_index, mid+max);
|
||||
i += 2;
|
||||
}
|
||||
s->preview_audio_index++;
|
||||
|
||||
+7
-2
@@ -23,12 +23,15 @@
|
||||
#define OLIVE_FILE_FILTER "Olive Project (*.ove)"
|
||||
|
||||
void MainWindow::setup_layout() {
|
||||
panel_project->show();
|
||||
panel_effect_controls->show();
|
||||
panel_viewer->show();
|
||||
panel_timeline->show();
|
||||
|
||||
addDockWidget(Qt::TopDockWidgetArea, panel_project);
|
||||
addDockWidget(Qt::TopDockWidgetArea, panel_effect_controls);
|
||||
addDockWidget(Qt::TopDockWidgetArea, panel_viewer);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, panel_timeline);
|
||||
|
||||
setCentralWidget(NULL);
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
@@ -66,6 +69,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
setWindowTitle("Olive (May 2018 | Pre-Alpha)");
|
||||
statusBar()->showMessage("Welcome to Olive::Qt");
|
||||
|
||||
setCentralWidget(NULL);
|
||||
|
||||
// TODO maybe replace these with non-pointers later on?
|
||||
panel_project = new Project(this);
|
||||
panel_effect_controls = new EffectControls(this);
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuPlayback">
|
||||
<property name="title">
|
||||
<string>Playback</string>
|
||||
<string>&Playback</string>
|
||||
</property>
|
||||
<addaction name="actionGo_to_start"/>
|
||||
<addaction name="actionPrevious_Frame"/>
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.6.2, 2018-06-18T23:37:22. -->
|
||||
<!-- Written by QtCreator 4.6.2, 2018-06-19T11:17:03. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
||||
+5
-3
@@ -80,13 +80,12 @@ void Timeline::seek(long p) {
|
||||
repaint_timeline();
|
||||
}
|
||||
|
||||
bool Timeline::toggle_play() {
|
||||
void Timeline::toggle_play() {
|
||||
if (playing) {
|
||||
pause();
|
||||
} else {
|
||||
play();
|
||||
}
|
||||
return playing;
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::play() {
|
||||
@@ -94,10 +93,12 @@ void Timeline::play() {
|
||||
start_msecs = QDateTime::currentMSecsSinceEpoch();
|
||||
playback_updater.start();
|
||||
playing = true;
|
||||
panel_viewer->set_playpause_icon(false);
|
||||
}
|
||||
|
||||
void Timeline::pause() {
|
||||
playing = false;
|
||||
panel_viewer->set_playpause_icon(true);
|
||||
}
|
||||
|
||||
void Timeline::go_to_end() {
|
||||
@@ -167,6 +168,7 @@ void Timeline::redraw_all_clips() {
|
||||
|
||||
ui->video_area->redraw_clips();
|
||||
ui->audio_area->redraw_clips();
|
||||
ui->headers->update();
|
||||
}
|
||||
|
||||
void Timeline::select_all() {
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ public:
|
||||
void previous_frame();
|
||||
void next_frame();
|
||||
void seek(long p);
|
||||
bool toggle_play();
|
||||
void toggle_play();
|
||||
void play();
|
||||
void pause();
|
||||
void go_to_end();
|
||||
|
||||
+9
-6
@@ -71,10 +71,13 @@ void Viewer::on_pushButton_4_clicked()
|
||||
|
||||
void Viewer::on_pushButton_3_clicked()
|
||||
{
|
||||
if (panel_timeline->toggle_play()) {
|
||||
// playing
|
||||
ui->pushButton_3->setIcon(QIcon(":/icons/pause.png"));
|
||||
} else {
|
||||
ui->pushButton_3->setIcon(QIcon(":/icons/play.png"));
|
||||
}
|
||||
panel_timeline->toggle_play();
|
||||
}
|
||||
|
||||
void Viewer::set_playpause_icon(bool play) {
|
||||
if (play) {
|
||||
ui->pushButton_3->setIcon(QIcon(":/icons/play.png"));
|
||||
} else {
|
||||
ui->pushButton_3->setIcon(QIcon(":/icons/pause.png"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
~Viewer();
|
||||
void update_sequence();
|
||||
void compose();
|
||||
void set_playpause_icon(bool play);
|
||||
|
||||
ViewerWidget* viewer_widget;
|
||||
|
||||
|
||||
+3
-1
@@ -37,7 +37,9 @@ void init_audio() {
|
||||
if (!info.isFormatSupported(audio_format)) {
|
||||
qWarning() << "[WARNING] Couldn't initialize audio. Audio format is not supported by backend";
|
||||
} else {
|
||||
audio_output = new QAudioOutput(audio_format);
|
||||
audio_output = new QAudioOutput(audio_format);
|
||||
audio_output->setBufferSize(20480);
|
||||
|
||||
// connect
|
||||
audio_io_device = audio_output->start();
|
||||
audio_device_set = true;
|
||||
|
||||
@@ -40,7 +40,12 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
|
||||
if (sequence != NULL) {
|
||||
QPainter p(this);
|
||||
p.setPen(Qt::gray);
|
||||
int interval = panel_timeline->getScreenPointFromFrame(sequence->frame_rate);
|
||||
int interval = 0;
|
||||
int multiplier = 0;
|
||||
do {
|
||||
multiplier++;
|
||||
interval = panel_timeline->getScreenPointFromFrame(sequence->frame_rate*multiplier);
|
||||
} while (interval < 10);
|
||||
for (int i=0;i<width();i+=interval) {
|
||||
p.drawLine(i, 0, i, height());
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent)
|
||||
setMouseTracking(true);
|
||||
track_height = 80;
|
||||
|
||||
setAcceptDrops(true);
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
|
||||
bool same_sign(int a, int b) {
|
||||
@@ -760,8 +760,6 @@ int color_brightness(int r, int g, int b) {
|
||||
}
|
||||
|
||||
void TimelineWidget::redraw_clips() {
|
||||
qDebug() << "redraw called";
|
||||
|
||||
// Draw clips
|
||||
int panel_width = panel_timeline->getScreenPointFromFrame(sequence->getEndFrame()) + 100;
|
||||
|
||||
@@ -817,6 +815,11 @@ void TimelineWidget::redraw_clips() {
|
||||
}
|
||||
QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - CLIP_TEXT_PADDING, clip_rect.height() - CLIP_TEXT_PADDING - CLIP_TEXT_PADDING);
|
||||
clip_painter.drawText(text_rect, 0, clip->name, &text_rect);
|
||||
if (clip->linked.size() > 0) {
|
||||
int underline_y = CLIP_TEXT_PADDING + clip_painter.fontMetrics().height() + clip_rect.top();
|
||||
int underline_width = qMin(clip_rect.width() - CLIP_TEXT_PADDING, clip_rect.left() + CLIP_TEXT_PADDING+clip_painter.fontMetrics().width(clip->name));
|
||||
clip_painter.drawLine(clip_rect.left() + CLIP_TEXT_PADDING, underline_y, underline_width, underline_y);
|
||||
}
|
||||
|
||||
// bottom right gray
|
||||
clip_painter.setPen(Qt::gray);
|
||||
|
||||
Reference in New Issue
Block a user