📄 hplx_vert_synthesis_by_lifting.c
字号:
{ /* This step ensures that the update lifting steps identify
the incremental DC gain relative to the output of the previous
update step, rather than the absolute DC gain at the end of
each step. */
step = self->steps + n;
step_gain = step->dc_gain / current_gain;
current_gain = step->dc_gain;
step->dc_gain = step_gain;
}
}
/* Now determine tile and frame dimensions and attributes. */
self->rows_left_in_tile = dims->rows;
self->first_row_idx_in_frame = dims->top_row;
self->heap.buffer_length = dims->cols;
for (n=0; n < self->num_buffering_stages; n++)
self->buffering_stages[n].base.cols = dims->cols;
info->get_level_info(info,base->component_idx,base->level_idx,
NULL,NULL,&frame,NULL);
if (frame.vert_ssodwt)
{
int uses_overlap;
/* First check that filters use overlap. */
for (uses_overlap=0, n=0; n < self->num_steps; n++)
if (((n & 1)==0) && (self->steps[n].pos_support > 0))
uses_overlap = 1; /* Prediction step uses overlapping boundary */
if (!uses_overlap)
local_error("The 1-sample overlap method has no effect whatsoever "
"if all update steps in the lifting implementation of "
"the filter have only two taps! The method was designed "
"for use with odd length filters.");
/* Now for the frame dimensions and location. */
self->frame_rows = frame_dims->rows;
self->frame_ref = frame_dims->top_row;
self->first_frame_rows = frame_dims->rows -
((dims->top_row - frame_dims->top_row) & (frame_dims->rows - 1));
if (self->first_frame_rows >= dims->rows)
{
self->first_frame_rows = dims->rows;
self->num_frames = 1;
}
else
self->num_frames = 2 +
(dims->rows - self->first_frame_rows - 1) / frame_dims->rows;
}
else
{
self->num_frames = 1;
self->frame_rows = self->first_frame_rows = dims->rows;
self->frame_ref = dims->top_row;
}
/* Now perform branch initialization. */
for (b=0; b < base->vert_limit; b++)
{
canvas_dims branch_dims, branch_frame_dims;
int top, bottom;
self->buffering_stages[b].base.num_users++;
/* The process which pulls even and odd rows from the first two
buffering stages is understood as an additional user. */
branch_dims = *dims;
if (base->vert_limit > 1) {
top = branch_dims.top_row;
bottom = top + branch_dims.rows - 1;
top = (top+1-b)>>1;
bottom = (bottom-b)>>1;
branch_dims.top_row = top;
branch_dims.rows = bottom+1-top;
}
branch_frame_dims = *frame_dims;
if (base->vert_limit > 1) {
branch_frame_dims.rows >>= 1;
branch_frame_dims.top_row = (branch_frame_dims.top_row+1-b)>>1;
}
base->branches[b]->initialize(base->branches[b],info,
&branch_dims,&branch_frame_dims);
}
start_vertical_frame(self,NULL);
}
/*****************************************************************************/
/* __pull_line_fixed */
/*****************************************************************************/
static void
__pull_line_fixed(hplx_synthesis_stage_ref base, ifc_int *line_buf,
int width)
{
hplx_vert_synthesis_by_lifting_ref self =
(hplx_vert_synthesis_by_lifting_ref) base;
hplx_buffering_stage_ptr stage;
hplx_row_buffer_state_ptr buf;
int n, next_row_idx;
if (base->vert_limit > 1) {
next_row_idx = self->current_frame_rows - self->rows_left_in_frame +
(self->first_row_idx_in_frame & 1);
stage = &(self->buffering_stages[1-(next_row_idx&1)].base);
assert(stage->cols == width);
if (width == 0)
return;
assert(self->rows_left_in_frame > 0);
if (self->buffering_stages[next_row_idx&1].base.rows == 0)
{ /* Signals of length < 2 must be treated specially. */
self->rows_left_in_frame--;
assert((self->rows_left_in_frame == 0) &&
(self->current_frame_rows == 1));
/* Fix for single sample discrepancy between VM8.5 and FDIS */
if (!stage->skip_last)
{
base->branches[next_row_idx&1]->pull_line_fixed(
base->branches[next_row_idx&1],line_buf,width);
if ((self->current_frame_rows == 1) &&
(self->first_row_idx_in_frame & 1))
{
ifc_int *sp;
for (sp=line_buf, n=width; n > 0; n--)
{
*(sp++) >>= 1;
}
}
}
self->frame_idx++;
if (self->frame_idx < self->num_frames)
{
start_vertical_frame(self,NULL);
if (stage->special_first)
__pull_line_fixed(base,line_buf,width);
}
return;
}
/* Find index of next row in relevant sub-sequence, relative to first
row in that subsequence. */
next_row_idx = (next_row_idx >> 1) - stage->missing_first_row;
assert(next_row_idx >= 0);
hplx_lift_stage__get_rows(stage,next_row_idx,1,&buf);
hplx_lift_stage__release_row(stage,next_row_idx);
if (buf->float_buf != NULL)
{
float *sp, val;
ifc_int *dp;
for (dp=line_buf, sp=buf->float_buf, n=width; n > 0; n--)
{
val = *(sp++);
*(dp++) = (ifc_int)((val<0.0F)?(val-0.5F):(val+0.5F));
}
}
else
{
ifc_int *sp, *dp;
for (dp=line_buf, sp=buf->int_buf, n=width; n > 0; n--)
*(dp++) = *(sp++);
}
/* Advance frame counters and move onto next frame if necessary. */
self->rows_left_in_frame--;
if (self->rows_left_in_frame == 0)
{
self->frame_idx++;
if (self->frame_idx < self->num_frames)
{
start_vertical_frame(self,buf);
if (stage->special_first)
{
if (self->current_frame_rows == 1)
{ /* This frame consists only in the overlap row. */
self->rows_left_in_frame = 0;
self->frame_idx++;
assert(self->frame_idx == self->num_frames);
}
else
__pull_line_fixed(base,line_buf,width);
}
}
}
}
else {
if (base->use_floats) {
ifc_int *dp;
float *sp, *tmp_buf;
tmp_buf = (float *) local_malloc(XFORM_MEM_KEY, width*sizeof(float));
base->branches[0]->pull_line_float(base->branches[0],tmp_buf,width);
for (dp=line_buf, sp=tmp_buf, n=width; n > 0; n--)
*(dp++) = (ifc_int) *(sp++);
local_free(tmp_buf);
}
else {
base->branches[0]->pull_line_fixed(base->branches[0],line_buf,width);
}
}
}
/*****************************************************************************/
/* __pull_line_float */
/*****************************************************************************/
static void
__pull_line_float(hplx_synthesis_stage_ref base, float *line_buf,
int width)
{
hplx_vert_synthesis_by_lifting_ref self =
(hplx_vert_synthesis_by_lifting_ref) base;
hplx_buffering_stage_ptr stage;
hplx_row_buffer_state_ptr buf;
float *sp, *dp;
int n, next_row_idx;
if (base->vert_limit > 1) {
next_row_idx = self->current_frame_rows - self->rows_left_in_frame +
(self->first_row_idx_in_frame & 1);
stage = &(self->buffering_stages[1-(next_row_idx&1)].base);
assert(stage->cols == width);
if (width == 0)
return;
assert(self->rows_left_in_frame > 0);
if (self->buffering_stages[next_row_idx&1].base.rows == 0)
{ /* Signals of length < 2 must be treated specially. */
self->rows_left_in_frame--;
assert((self->rows_left_in_frame == 0) &&
(self->current_frame_rows == 1));
if (!stage->skip_last)
base->branches[next_row_idx&1]->pull_line_float(
base->branches[next_row_idx&1],line_buf,width);
self->frame_idx++;
if (self->frame_idx < self->num_frames)
{
start_vertical_frame(self,NULL);
if (stage->special_first)
__pull_line_float(base,line_buf,width);
}
return;
}
/* Find index of next row in relevant sub-sequence, relative to first
row in that subsequence. */
next_row_idx = (next_row_idx >> 1) - stage->missing_first_row;
assert(next_row_idx >= 0);
hplx_lift_stage__get_rows(stage,next_row_idx,1,&buf);
hplx_lift_stage__release_row(stage,next_row_idx);
for (dp=line_buf, sp=buf->float_buf, n=width; n > 0; n--)
*(dp++) = *(sp++);
/* Advance frame counters and move onto next frame if necessary. */
self->rows_left_in_frame--;
if (self->rows_left_in_frame == 0)
{
self->frame_idx++;
if (self->frame_idx < self->num_frames)
{
start_vertical_frame(self,buf);
if (stage->special_first)
{
if (self->current_frame_rows == 1)
{ /* This frame consists only in the overlap row. */
self->rows_left_in_frame = 0;
self->frame_idx++;
assert(self->frame_idx == self->num_frames);
}
else
__pull_line_float(base,line_buf,width);
}
}
}
}
else{
base->branches[0]->pull_line_float(base->branches[0],line_buf,width);
}
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static void
__terminate(hplx_synthesis_stage_ref base)
{
hplx_vert_synthesis_by_lifting_ref self =
(hplx_vert_synthesis_by_lifting_ref) base;
hplx_row_buffer_state_ptr buf;
hplx_buffering_stage_ptr stage;
int b, n, num_buffers;
if (self->steps != NULL)
local_free(self->steps);
if (self->buffering_stages != NULL)
{
for (n=0; n < self->num_buffering_stages; n++)
{
stage = &(self->buffering_stages[n].base);
if (stage->row_buffers != NULL)
{
num_buffers = stage->next_row_idx - stage->min_row_idx;
for (b=0; b < num_buffers; b++)
hplx_lift_heap__return_buffer(stage->heap,
stage->row_buffers[b]);
local_free(stage->row_buffers);
}
}
local_free(self->buffering_stages);
}
while ((buf=self->heap.head) != NULL)
{
self->heap.head = buf->next;
if (buf->float_buf != NULL)
local_free(buf->float_buf);
if (buf->int_buf != NULL)
local_free(buf->int_buf);
local_free(buf);
}
for (b=0; b < base->vert_limit; b++)
base->branches[b]->terminate(base->branches[b]);
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_hplx_vert_synthesis_by_lifting */
/*****************************************************************************/
hplx_synthesis_stage_ref
create_hplx_vert_synthesis_by_lifting(void)
{
hplx_vert_synthesis_by_lifting_ref result;
result = (hplx_vert_synthesis_by_lifting_ref)
local_malloc(XFORM_MEM_KEY,sizeof(hplx_vert_synthesis_by_lifting_obj));
result->base.initialize = __initialize;
result->base.pull_line_fixed = __pull_line_fixed;
result->base.pull_line_float = __pull_line_float;
result->base.terminate = __terminate;
return((hplx_synthesis_stage_ref) result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -