parent
011d3c75a7
commit
82f65d8971
|
@ -241,329 +241,296 @@ typedef struct WaveVizData {
|
|||
float pos[2];
|
||||
float rms_pos;
|
||||
bool clip;
|
||||
bool end;
|
||||
bool draw_line; /* Draw triangle otherwise. */
|
||||
bool final_sample; /* There are no more samples. */
|
||||
} WaveVizData;
|
||||
|
||||
static int get_section_len(WaveVizData *start, WaveVizData *end)
|
||||
static bool seq_draw_waveforms_poll(const bContext *C, SpaceSeq *sseq, Sequence *seq)
|
||||
{
|
||||
int len = 0;
|
||||
while (start != end) {
|
||||
len++;
|
||||
if (start->end) {
|
||||
return len;
|
||||
}
|
||||
start++;
|
||||
const bool strip_is_valid = seq->type == SEQ_TYPE_SOUND_RAM && seq->sound != NULL;
|
||||
const bool overlays_enabled = (sseq->flag & SEQ_SHOW_OVERLAY) != 0;
|
||||
const bool ovelay_option = ((sseq->timeline_overlay.flag & SEQ_TIMELINE_ALL_WAVEFORMS) != 0 ||
|
||||
(seq->flag & SEQ_AUDIO_DRAW_WAVEFORM));
|
||||
|
||||
if ((sseq->timeline_overlay.flag & SEQ_TIMELINE_NO_WAVEFORMS) != 0) {
|
||||
return false;
|
||||
}
|
||||
return len;
|
||||
|
||||
if (strip_is_valid && overlays_enabled && ovelay_option) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void draw_waveform(WaveVizData *iter, WaveVizData *end, GPUPrimType prim_type, bool use_rms)
|
||||
static void waveform_job_start_if_needed(const bContext *C, Sequence *seq)
|
||||
{
|
||||
int strip_len = get_section_len(iter, end);
|
||||
if (strip_len > 1) {
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
bSound *sound = seq->sound;
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
|
||||
immBegin(prim_type, strip_len);
|
||||
|
||||
while (iter != end) {
|
||||
if (iter->clip) {
|
||||
immAttr4f(col, 1.0f, 0.0f, 0.0f, 0.5f);
|
||||
}
|
||||
else if (use_rms) {
|
||||
immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.8f);
|
||||
}
|
||||
else {
|
||||
immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.5f);
|
||||
}
|
||||
|
||||
if (use_rms) {
|
||||
immVertex2f(pos, iter->pos[0], iter->rms_pos);
|
||||
}
|
||||
else {
|
||||
immVertex2f(pos, iter->pos[0], iter->pos[1]);
|
||||
}
|
||||
|
||||
if (iter->end) {
|
||||
/* End of line. */
|
||||
iter++;
|
||||
strip_len = get_section_len(iter, end);
|
||||
if (strip_len != 0) {
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
|
||||
immBegin(prim_type, strip_len);
|
||||
}
|
||||
}
|
||||
else {
|
||||
iter++;
|
||||
}
|
||||
BLI_spin_lock(sound->spinlock);
|
||||
if (!sound->waveform) {
|
||||
/* Load the waveform data if it hasn't been loaded and cached already. */
|
||||
if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
|
||||
/* Prevent sounds from reloading. */
|
||||
sound->tags |= SOUND_TAGS_WAVEFORM_LOADING;
|
||||
BLI_spin_unlock(sound->spinlock);
|
||||
sequencer_preview_add_sound(C, seq);
|
||||
}
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
else {
|
||||
BLI_spin_unlock(sound->spinlock);
|
||||
}
|
||||
}
|
||||
BLI_spin_unlock(sound->spinlock);
|
||||
}
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
static size_t get_vertex_count(WaveVizData *waveform_data)
|
||||
{
|
||||
bool draw_line = waveform_data->draw_line;
|
||||
size_t length = 0;
|
||||
|
||||
while (waveform_data->draw_line == draw_line && !waveform_data->final_sample) {
|
||||
waveform_data++;
|
||||
length++;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static size_t draw_waveform_segment(WaveVizData *waveform_data, bool use_rms)
|
||||
{
|
||||
size_t vertices_done = 0;
|
||||
size_t vertex_count = get_vertex_count(waveform_data);
|
||||
|
||||
/* Not enough data to draw. */
|
||||
if (vertex_count <= 2) {
|
||||
return vertex_count;
|
||||
}
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
GPUPrimType prim_type = waveform_data->draw_line ? GPU_PRIM_LINE_STRIP : GPU_PRIM_TRI_STRIP;
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
|
||||
immBegin(prim_type, vertex_count);
|
||||
|
||||
while (vertices_done < vertex_count && !waveform_data->final_sample) {
|
||||
/* Color. */
|
||||
if (waveform_data->clip) {
|
||||
immAttr4f(col, 1.0f, 0.0f, 0.0f, 0.5f);
|
||||
}
|
||||
else if (use_rms) {
|
||||
immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.8f);
|
||||
}
|
||||
else {
|
||||
immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.5f);
|
||||
}
|
||||
|
||||
/* Vertices. */
|
||||
if (use_rms) {
|
||||
immVertex2f(pos, waveform_data->pos[0], waveform_data->rms_pos);
|
||||
}
|
||||
else {
|
||||
immVertex2f(pos, waveform_data->pos[0], waveform_data->pos[1]);
|
||||
}
|
||||
|
||||
vertices_done++;
|
||||
waveform_data++;
|
||||
}
|
||||
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
|
||||
return vertices_done;
|
||||
}
|
||||
|
||||
static void draw_waveform(WaveVizData *waveform_data, size_t wave_data_len)
|
||||
{
|
||||
size_t items_done = 0;
|
||||
while (items_done < wave_data_len) {
|
||||
if (!waveform_data[items_done].draw_line) { /* Draw RMS. */
|
||||
draw_waveform_segment(&waveform_data[items_done], true);
|
||||
}
|
||||
items_done += draw_waveform_segment(&waveform_data[items_done], false);
|
||||
}
|
||||
}
|
||||
|
||||
static float clamp_frame_coord_to_pixel(float frame_coord,
|
||||
float pixel_frac,
|
||||
float frames_per_pixel)
|
||||
static float align_frame_with_pixel(const View2D *v2d, float frame_coord, float frames_per_pixel)
|
||||
{
|
||||
float cur_pixel = (frame_coord / frames_per_pixel);
|
||||
float new_pixel = (int)(frame_coord / frames_per_pixel) + pixel_frac;
|
||||
if (cur_pixel > new_pixel) {
|
||||
new_pixel += 1.0f;
|
||||
return round_fl_to_int(frame_coord / frames_per_pixel) * frames_per_pixel;
|
||||
}
|
||||
|
||||
static void write_waveform_data(WaveVizData *waveform_data,
|
||||
const vec2f pos,
|
||||
const float rms,
|
||||
const bool is_clipping,
|
||||
const bool draw_line)
|
||||
{
|
||||
waveform_data->pos[0] = pos.x;
|
||||
waveform_data->pos[1] = pos.y;
|
||||
waveform_data->clip = is_clipping;
|
||||
waveform_data->rms_pos = rms;
|
||||
waveform_data->draw_line = draw_line;
|
||||
}
|
||||
|
||||
static size_t waveform_append_sample(WaveVizData *waveform_data,
|
||||
vec2f pos,
|
||||
const float value_min,
|
||||
const float value_max,
|
||||
const float y_mid,
|
||||
const float y_scale,
|
||||
const float rms,
|
||||
const bool is_clipping,
|
||||
const bool is_line_strip)
|
||||
{
|
||||
size_t data_written = 0;
|
||||
pos.y = y_mid + value_min * y_scale;
|
||||
float rms_value = y_mid + max_ff(-rms, value_min) * y_scale;
|
||||
write_waveform_data(&waveform_data[0], pos, rms_value, is_clipping, is_line_strip);
|
||||
data_written++;
|
||||
|
||||
/* Use `value_max` as second vertex for triangle drawing. */
|
||||
if (!is_line_strip) {
|
||||
pos.y = y_mid + value_max * y_scale;
|
||||
rms_value = y_mid + min_ff(rms, value_max) * y_scale;
|
||||
write_waveform_data(&waveform_data[1], pos, rms_value, is_clipping, is_line_strip);
|
||||
data_written++;
|
||||
}
|
||||
return new_pixel * frames_per_pixel;
|
||||
return data_written;
|
||||
}
|
||||
|
||||
/**
|
||||
* \param x1, x2, y1, y2: The starting and end X value to draw the wave, same for y1 and y2.
|
||||
* \param frames_per_pixel: The amount of pixels a whole frame takes up (x-axis direction).
|
||||
*/
|
||||
static void draw_seq_waveform_overlay(View2D *v2d,
|
||||
const bContext *C,
|
||||
SpaceSeq *sseq,
|
||||
Scene *scene,
|
||||
Sequence *seq,
|
||||
float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
float frames_per_pixel)
|
||||
static void draw_seq_waveform_overlay(
|
||||
const bContext *C, ARegion *region, Sequence *seq, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
if (seq->sound && ((sseq->timeline_overlay.flag & SEQ_TIMELINE_ALL_WAVEFORMS) ||
|
||||
(seq->flag & SEQ_AUDIO_DRAW_WAVEFORM))) {
|
||||
/* Make sure that the start drawing position is aligned to the pixels on the screen to avoid
|
||||
* flickering when moving around the strip.
|
||||
* To do this we figure out the fractional offset in pixel space by checking where the
|
||||
* window starts.
|
||||
* We then append this pixel offset to our strip start coordinate to ensure we are aligned to
|
||||
* the screen pixel grid. */
|
||||
float pixel_frac = v2d->cur.xmin / frames_per_pixel - floor(v2d->cur.xmin / frames_per_pixel);
|
||||
float x1_adj = clamp_frame_coord_to_pixel(x1, pixel_frac, frames_per_pixel);
|
||||
const View2D *v2d = ®ion->v2d;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
/* Offset x1 and x2 values, to match view min/max, if strip is out of bounds. */
|
||||
float x1_offset = max_ff(v2d->cur.xmin, x1_adj);
|
||||
float x2_offset = min_ff(v2d->cur.xmax, x2);
|
||||
const float frames_per_pixel = BLI_rctf_size_x(®ion->v2d.cur) / region->winx;
|
||||
const float samples_per_frame = SOUND_WAVE_SAMPLES_PER_SECOND / FPS;
|
||||
float samples_per_pixel = samples_per_frame * frames_per_pixel;
|
||||
|
||||
/* Calculate how long the strip that is in view is in pixels. */
|
||||
int pix_strip_len = round((x2_offset - x1_offset) / frames_per_pixel);
|
||||
/* Align strip start with nearest pixel to prevent waveform flickering. */
|
||||
const float x1_aligned = align_frame_with_pixel(v2d, x1, frames_per_pixel);
|
||||
/* Offset x1 and x2 values, to match view min/max, if strip is out of bounds. */
|
||||
const float frame_start = max_ff(v2d->cur.xmin, x1_aligned);
|
||||
const float frame_end = min_ff(v2d->cur.xmax, x2);
|
||||
const int pixels_to_draw = round_fl_to_int((frame_end - frame_start) / frames_per_pixel);
|
||||
|
||||
if (pix_strip_len < 2) {
|
||||
return;
|
||||
if (pixels_to_draw < 2) {
|
||||
return; /* Not much to draw, exit before running job. */
|
||||
}
|
||||
|
||||
waveform_job_start_if_needed(C, seq);
|
||||
|
||||
SoundWaveform *waveform = seq->sound->waveform;
|
||||
if (waveform == NULL || waveform->length == 0) {
|
||||
return; /* Waveform was not built. */
|
||||
}
|
||||
|
||||
/* F-Curve lookup is quite expensive, so do this after precondition. */
|
||||
FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL);
|
||||
WaveVizData *waveform_data = MEM_callocN(sizeof(WaveVizData) * pixels_to_draw * 3, __func__);
|
||||
size_t wave_data_len = 0;
|
||||
|
||||
/* Offset must be also aligned, otherwise waveform flickers when moving left handle. */
|
||||
const float strip_offset = align_frame_with_pixel(
|
||||
v2d, seq->startofs + seq->anim_startofs, frames_per_pixel);
|
||||
float start_sample = strip_offset * samples_per_frame;
|
||||
start_sample += seq->sound->offset_time * SOUND_WAVE_SAMPLES_PER_SECOND;
|
||||
/* Add off-screen part of strip to offset. */
|
||||
start_sample += (frame_start - x1_aligned) * samples_per_frame;
|
||||
|
||||
for (int i = 0; i < pixels_to_draw; i++) {
|
||||
float sample = start_sample + i * samples_per_pixel;
|
||||
int sample_index = round_fl_to_int(sample);
|
||||
|
||||
if (sample_index < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bSound *sound = seq->sound;
|
||||
if (sample_index >= waveform->length) {
|
||||
break;
|
||||
}
|
||||
|
||||
BLI_spin_lock(sound->spinlock);
|
||||
if (!sound->waveform) {
|
||||
/* Load the waveform data if it hasn't been loaded and cached already. */
|
||||
if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
|
||||
/* Prevent sounds from reloading. */
|
||||
sound->tags |= SOUND_TAGS_WAVEFORM_LOADING;
|
||||
BLI_spin_unlock(sound->spinlock);
|
||||
sequencer_preview_add_sound(C, seq);
|
||||
float value_min = waveform->data[sample_index * 3];
|
||||
float value_max = waveform->data[sample_index * 3 + 1];
|
||||
float rms = waveform->data[sample_index * 3 + 2];
|
||||
|
||||
if (sample_index + 1 < waveform->length) {
|
||||
/* Use simple linear interpolation. */
|
||||
float f = sample - sample_index;
|
||||
value_min = (1.0f - f) * value_min + f * waveform->data[sample_index * 3 + 3];
|
||||
value_max = (1.0f - f) * value_max + f * waveform->data[sample_index * 3 + 4];
|
||||
rms = (1.0f - f) * rms + f * waveform->data[sample_index * 3 + 5];
|
||||
if (samples_per_pixel > 1.0f) {
|
||||
/* We need to sum up the values we skip over until the next step. */
|
||||
float next_pos = sample + samples_per_pixel;
|
||||
int end_idx = next_pos;
|
||||
|
||||
for (int j = sample_index + 1; (j < waveform->length) && (j < end_idx); j++) {
|
||||
value_min = min_ff(value_min, waveform->data[j * 3]);
|
||||
value_max = max_ff(value_max, waveform->data[j * 3 + 1]);
|
||||
rms = max_ff(rms, waveform->data[j * 3 + 2]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_spin_unlock(sound->spinlock);
|
||||
}
|
||||
return; /* Nothing to draw. */
|
||||
}
|
||||
BLI_spin_unlock(sound->spinlock);
|
||||
|
||||
SoundWaveform *waveform = sound->waveform;
|
||||
|
||||
/* Waveform could not be built. */
|
||||
if (waveform->length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* F-Curve lookup is quite expensive, so do this after precondition. */
|
||||
FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL);
|
||||
float volume = seq->volume;
|
||||
if (fcu && !BKE_fcurve_is_empty(fcu)) {
|
||||
float evaltime = frame_start + (i * frames_per_pixel);
|
||||
volume = evaluate_fcurve(fcu, evaltime);
|
||||
CLAMP_MIN(volume, 0.0f);
|
||||
}
|
||||
|
||||
WaveVizData *tri_strip_arr = MEM_callocN(sizeof(*tri_strip_arr) * pix_strip_len * 2,
|
||||
"tri_strip");
|
||||
WaveVizData *line_strip_arr = MEM_callocN(sizeof(*line_strip_arr) * pix_strip_len,
|
||||
"line_strip");
|
||||
value_min *= volume;
|
||||
value_max *= volume;
|
||||
rms *= volume;
|
||||
|
||||
WaveVizData *tri_strip_iter = tri_strip_arr;
|
||||
WaveVizData *line_strip_iter = line_strip_arr;
|
||||
bool is_clipping = false;
|
||||
|
||||
if (value_max > 1 || value_min < -1) {
|
||||
is_clipping = true;
|
||||
|
||||
CLAMP_MAX(value_max, 1.0f);
|
||||
CLAMP_MIN(value_min, -1.0f);
|
||||
}
|
||||
|
||||
bool is_line_strip = (value_max - value_min < 0.05f);
|
||||
/* The y coordinate for the middle of the strip. */
|
||||
float y_mid = (y1 + y2) / 2.0f;
|
||||
/* The length from the middle of the strip to the top/bottom. */
|
||||
float y_scale = (y2 - y1) / 2.0f;
|
||||
float volume = seq->volume;
|
||||
|
||||
/* Value to keep track if the previous item to be drawn was a line strip. */
|
||||
int8_t was_line_strip = -1; /* -1 == no previous value. */
|
||||
|
||||
float samples_per_frame = SOUND_WAVE_SAMPLES_PER_SECOND / FPS;
|
||||
|
||||
/* How many samples do we have for each pixel? */
|
||||
float samples_per_pix = samples_per_frame * frames_per_pixel;
|
||||
|
||||
float strip_start_offset = seq->startofs + seq->anim_startofs;
|
||||
float start_sample = 0;
|
||||
|
||||
if (strip_start_offset != 0) {
|
||||
/* If start offset is not zero, we need to make sure that we pick the same start sample as if
|
||||
* we simply scrolled the start of the strip off-screen. Otherwise we will get flickering
|
||||
* when changing start offset as the pixel alignment will not be the same for the drawn
|
||||
* samples. */
|
||||
strip_start_offset = clamp_frame_coord_to_pixel(
|
||||
x1 - strip_start_offset, pixel_frac, frames_per_pixel);
|
||||
start_sample = fabsf(strip_start_offset - x1_adj) * samples_per_frame;
|
||||
}
|
||||
|
||||
start_sample += seq->sound->offset_time * SOUND_WAVE_SAMPLES_PER_SECOND;
|
||||
/* If we scrolled the start off-screen, then the start sample should be at the first visible
|
||||
* sample. */
|
||||
start_sample += (x1_offset - x1_adj) * samples_per_frame;
|
||||
|
||||
for (int i = 0; i < pix_strip_len; i++) {
|
||||
float sample_offset = start_sample + i * samples_per_pix;
|
||||
int p = sample_offset;
|
||||
|
||||
if (p < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p >= waveform->length) {
|
||||
break;
|
||||
}
|
||||
|
||||
float value_min = waveform->data[p * 3];
|
||||
float value_max = waveform->data[p * 3 + 1];
|
||||
float rms = waveform->data[p * 3 + 2];
|
||||
|
||||
if (p + 1 < waveform->length) {
|
||||
/* Use simple linear interpolation. */
|
||||
float f = sample_offset - p;
|
||||
value_min = (1.0f - f) * value_min + f * waveform->data[p * 3 + 3];
|
||||
value_max = (1.0f - f) * value_max + f * waveform->data[p * 3 + 4];
|
||||
rms = (1.0f - f) * rms + f * waveform->data[p * 3 + 5];
|
||||
if (samples_per_pix > 1.0f) {
|
||||
/* We need to sum up the values we skip over until the next step. */
|
||||
float next_pos = sample_offset + samples_per_pix;
|
||||
int end_idx = next_pos;
|
||||
|
||||
for (int j = p + 1; (j < waveform->length) && (j < end_idx); j++) {
|
||||
value_min = min_ff(value_min, waveform->data[j * 3]);
|
||||
value_max = max_ff(value_max, waveform->data[j * 3 + 1]);
|
||||
rms = max_ff(rms, waveform->data[j * 3 + 2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fcu && !BKE_fcurve_is_empty(fcu)) {
|
||||
float evaltime = x1_offset + (i * frames_per_pixel);
|
||||
volume = evaluate_fcurve(fcu, evaltime);
|
||||
CLAMP_MIN(volume, 0.0f);
|
||||
}
|
||||
|
||||
value_min *= volume;
|
||||
value_max *= volume;
|
||||
rms *= volume;
|
||||
|
||||
bool clipping = false;
|
||||
|
||||
if (value_max > 1 || value_min < -1) {
|
||||
clipping = true;
|
||||
|
||||
CLAMP_MAX(value_max, 1.0f);
|
||||
CLAMP_MIN(value_min, -1.0f);
|
||||
}
|
||||
|
||||
bool is_line_strip = (value_max - value_min < 0.05f);
|
||||
|
||||
if (!ELEM(was_line_strip, -1, is_line_strip)) {
|
||||
/* If the previously added strip type isn't the same as the current one,
|
||||
* add transition areas so they transition smoothly between each other. */
|
||||
if (is_line_strip) {
|
||||
/* This will be a line strip, end the tri strip. */
|
||||
tri_strip_iter->pos[0] = x1_offset + i * frames_per_pixel;
|
||||
tri_strip_iter->pos[1] = y_mid + value_min * y_scale;
|
||||
tri_strip_iter->clip = clipping;
|
||||
tri_strip_iter->rms_pos = tri_strip_iter->pos[1];
|
||||
tri_strip_iter->end = true;
|
||||
|
||||
/* End of section. */
|
||||
tri_strip_iter++;
|
||||
|
||||
/* Check if we are at the end.
|
||||
* If so, skip one point line. */
|
||||
if (i + 1 == pix_strip_len) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* This will be a tri strip. */
|
||||
line_strip_iter--;
|
||||
tri_strip_iter->pos[0] = line_strip_iter->pos[0];
|
||||
tri_strip_iter->pos[1] = line_strip_iter->pos[1];
|
||||
tri_strip_iter->clip = line_strip_iter->clip;
|
||||
tri_strip_iter->rms_pos = line_strip_iter->pos[1];
|
||||
tri_strip_iter++;
|
||||
|
||||
/* Check if line had only one point. */
|
||||
line_strip_iter--;
|
||||
if (line_strip_iter < line_strip_arr || line_strip_iter->end) {
|
||||
/* Only one point, skip it. */
|
||||
line_strip_iter++;
|
||||
}
|
||||
else {
|
||||
/* End of section. */
|
||||
line_strip_iter++;
|
||||
line_strip_iter->end = true;
|
||||
line_strip_iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
was_line_strip = is_line_strip;
|
||||
|
||||
if (is_line_strip) {
|
||||
line_strip_iter->pos[0] = x1_offset + i * frames_per_pixel;
|
||||
line_strip_iter->pos[1] = y_mid + value_min * y_scale;
|
||||
line_strip_iter->clip = clipping;
|
||||
line_strip_iter++;
|
||||
}
|
||||
else {
|
||||
tri_strip_iter->pos[0] = x1_offset + i * frames_per_pixel;
|
||||
tri_strip_iter->pos[1] = y_mid + value_min * y_scale;
|
||||
tri_strip_iter->clip = clipping;
|
||||
tri_strip_iter->rms_pos = y_mid + max_ff(-rms, value_min) * y_scale;
|
||||
tri_strip_iter++;
|
||||
|
||||
tri_strip_iter->pos[0] = x1_offset + i * frames_per_pixel;
|
||||
tri_strip_iter->pos[1] = y_mid + value_max * y_scale;
|
||||
tri_strip_iter->clip = clipping;
|
||||
tri_strip_iter->rms_pos = y_mid + min_ff(rms, value_max) * y_scale;
|
||||
tri_strip_iter++;
|
||||
}
|
||||
}
|
||||
|
||||
WaveVizData *tri_strip_end = tri_strip_iter;
|
||||
WaveVizData *line_strip_end = line_strip_iter;
|
||||
|
||||
tri_strip_iter = tri_strip_arr;
|
||||
line_strip_iter = line_strip_arr;
|
||||
|
||||
draw_waveform(line_strip_iter, line_strip_end, GPU_PRIM_LINE_STRIP, false);
|
||||
draw_waveform(tri_strip_iter, tri_strip_end, GPU_PRIM_TRI_STRIP, false);
|
||||
draw_waveform(tri_strip_iter, tri_strip_end, GPU_PRIM_TRI_STRIP, true);
|
||||
|
||||
MEM_freeN(tri_strip_arr);
|
||||
MEM_freeN(line_strip_arr);
|
||||
vec2f pos = {frame_start + i * frames_per_pixel, y_mid + value_min * y_scale};
|
||||
WaveVizData *new_data = &waveform_data[wave_data_len];
|
||||
wave_data_len += waveform_append_sample(
|
||||
new_data, pos, value_min, value_max, y_mid, y_scale, rms, is_clipping, is_line_strip);
|
||||
}
|
||||
|
||||
/* Terminate array, so `get_segment_length()` can know when to stop. */
|
||||
waveform_data[wave_data_len].final_sample = true;
|
||||
draw_waveform(waveform_data, wave_data_len);
|
||||
MEM_freeN(waveform_data);
|
||||
}
|
||||
|
||||
/*
|
||||
static size_t *waveform_append(WaveVizData *waveform_data,
|
||||
vec2f pos,
|
||||
const float value_min,
|
||||
const float value_max,
|
||||
const float y_mid,
|
||||
const float y_scale,
|
||||
const float rms,
|
||||
const bool is_clipping,
|
||||
const bool is_line_strip)
|
||||
*/
|
||||
|
||||
static void drawmeta_contents(Scene *scene,
|
||||
Sequence *seqm,
|
||||
float x1,
|
||||
|
@ -1430,18 +1397,9 @@ static void draw_seq_strip(const bContext *C,
|
|||
}
|
||||
|
||||
/* Draw sound strip waveform. */
|
||||
if ((seq->type == SEQ_TYPE_SOUND_RAM) && ((sseq->flag & SEQ_SHOW_OVERLAY)) &&
|
||||
(sseq->timeline_overlay.flag & SEQ_TIMELINE_NO_WAVEFORMS) == 0) {
|
||||
draw_seq_waveform_overlay(v2d,
|
||||
C,
|
||||
sseq,
|
||||
scene,
|
||||
seq,
|
||||
x1,
|
||||
y_threshold ? y1 + 0.05f : y1,
|
||||
x2,
|
||||
y_threshold ? text_margin_y : y2,
|
||||
BLI_rctf_size_x(®ion->v2d.cur) / region->winx);
|
||||
if (seq_draw_waveforms_poll(C, sseq, seq)) {
|
||||
draw_seq_waveform_overlay(
|
||||
C, region, seq, x1, y_threshold ? y1 + 0.05f : y1, x2, y_threshold ? text_margin_y : y2);
|
||||
}
|
||||
/* Draw locked state. */
|
||||
if (SEQ_transform_is_locked(channels, seq)) {
|
||||
|
|
Loading…
Reference in New Issue