📄 codec_decoder.asm
字号:
.VAR audio_out_dc_remove_op_mono.param[$cbops.dc_remove.STRUC_SIZE] =
0, // Input index
0; // Output index
.ENDBLOCK;
.BLOCK $audio_out_warp_and_shift_op_mono;
.VAR audio_out_warp_and_shift_op_mono.next = $cbops.NO_MORE_OPERATORS;
.VAR audio_out_warp_and_shift_op_mono.func = &$cbops.warp_and_shift;
.VAR audio_out_warp_and_shift_op_mono.param[$cbops.warp_and_shift.STRUC_SIZE] =
0, // Input index
1, // Output index
-8, // Shift amount
&$WARP_FILTER_COEFS, // warp filter coefs
&audio_out_warp_and_shift_op.left_buf, // warp filter buffer
&$decoder_codec_stream_struc + $codec.stream_decode.WARP_TARGET_FIELD, // warp target address
(WARP_RATE_MAX_RAMP / 1000000 * TMR_PERIOD_AUDIO_COPY); // warp rate max ramp
.ENDBLOCK;
.VAR/DM1CIRC audio_out_warp_and_shift_op.left_buf[$WARP_FILTER_LENGTH];
.VAR/DM1CIRC audio_out_warp_and_shift_op.right_buf[$WARP_FILTER_LENGTH];
// ** allocate memory for codec stream structure **
.VAR/DM1 $decoder_codec_stream_struc[$codec.stream_decode.STRUC_SIZE] =
SELECTED_CODEC_FRAME_DECODE_FUNCTION, // frame_decode function
SELECTED_CODEC_RESET_DECODER_FUNCTION, // reset_decoder function
SELECTED_CODEC_SILENCE_DECODER_FUNCTION, // silence_decoder function
&$codec_in_cbuffer_struc, // in cbuffer
&$audio_out_left_cbuffer_struc, // out left cbuffer
&$audio_out_right_cbuffer_struc, // out right cbuffer
0, // internal mode data
0, // internal state data
COMFORT_NOISE_GAIN, // comfort noise gain
GOOD_WORKING_BUFFER_LEVEL, // good working buffer level %
POORLINK_DETECT_LEVEL, // poorlink detect buffer level %
POORLINK_PERIOD, // poorlink period (us)
ZERO_DATA_RATE_STOPPING, // playing -> stopping
// zero datarate period (us)
ZERO_DATA_RATE_BUFFERING, // buffering -> play out buffer
// zero datarate period (us)
&poorlink_detect_table, // poorlink detect table address
LENGTH(poorlink_detect_table), // poorlink detect table size
(WARP_RATE_HIGH_COEFFICIENT / 500), // warp rate high coefficient
(WARP_RATE_LOW_COEFFICIENT / 500), // warp rate low coefficient
WARP_RATE_TRANSITION_LEVEL_WORDS; // warp transition level in words
.VAR poorlink_detect_table[300];
// initialise the stack library
call $stack.initialise;
// initialise the interrupt library
call $interrupt.initialise;
// initialise the message library
call $message.initialise;
// initialise the cbuffer library
call $cbuffer.initialise;
.ifdef DEBUG_ON
// initialise the profiler library
call $profiler.initialise;
.endif
// initialise the codec decoder library
call SELECTED_CODEC_INITIALISE_DECODER_FUNCTION;
// tell vm we're ready and wait for the go message
call $message.send_ready_wait_for_go;
// see if left output port is connected
r0 = $AUDIO_LEFT_OUT_PORT;
call $cbuffer.is_it_enabled;
if NZ jump left_port_connected;
// tell codec library that no left buffer
M[$decoder_codec_stream_struc + $codec.stream_decode.OUT_LEFT_BUFFER_FIELD] = 0;
left_port_connected:
// see if right output port is connected
r0 = $AUDIO_RIGHT_OUT_PORT;
call $cbuffer.is_it_enabled;
if NZ jump right_port_connected;
// tell codec library that no right buffer
M[$decoder_codec_stream_struc + $codec.stream_decode.OUT_RIGHT_BUFFER_FIELD] = 0;
right_port_connected:
// wait for DAC buffers to have just wrapped around
wait_for_dac_buffer_wraparound:
r0 = $AUDIO_LEFT_OUT_PORT;
call $cbuffer.calc_amount_space;
// if the amount of space in the buffer is less than 16 bytes then a
// buffer wrap around must have just ocurred.
Null = r0 - 16;
if POS jump wait_for_dac_buffer_wraparound;
// start timer that copies output samples
r1 = &$audio_out_timer_struc;
r2 = TMR_PERIOD_AUDIO_COPY;
r3 = &$audio_out_copy_handler;
call $timer.schedule_event_in;
// start timer that copies codec input data
r1 = &$codec_in_timer_struc;
r2 = TMR_PERIOD_CODEC_COPY;
r3 = &$codec_in_copy_handler;
call $timer.schedule_event_in;
// continually decode codec frames
frame_loop:
// decode a frame
r5 = &$decoder_codec_stream_struc;
call $codec.stream_decode;
// idle as much as we can
Null = r0 - $codec.STREAM_CAN_IDLE;
if Z call $timer.1ms_delay;
jump frame_loop;
.ENDMODULE;
// *****************************************************************************
// MODULE:
// $audio_out_copy_handler
//
// DESCRIPTION:
// Function called on a timer interrupt to perform the mono or stereo copying
// of decoded samples to the output.
//
// *****************************************************************************
.MODULE $M.audio_out_copy_handler;
.CODESEGMENT PM;
.DATASEGMENT DM;
$audio_out_copy_handler:
// push rLink onto stack
$push_rLink_macro;
r8 = &$stereo_out_copy_struc;
r7 = &$mono_out_copy_struc;
// see if mono or stereo connection, based on whether the right output port
// is enabled
r0 = $AUDIO_RIGHT_OUT_PORT;
call $cbuffer.is_it_enabled;
if Z r8 = r7;
// Call the copy routine
call $cbops.copy;
// post another timer event
r1 = &$audio_out_timer_struc;
r2 = TMR_PERIOD_AUDIO_COPY;
r3 = &$audio_out_copy_handler;
call $timer.schedule_event_in_period;
// pop rLink from stack
jump $pop_rLink_and_rts;
.ENDMODULE;
// *****************************************************************************
// MODULE:
// $codec_in_copy_handler
//
// DESCRIPTION:
// Function called on a timer interrupt to perform the copying of encoded
// samples from the input.
//
// *****************************************************************************
.MODULE $M.codec_in_copy_handler;
.CODESEGMENT PM;
.DATASEGMENT DM;
$codec_in_copy_handler:
// push rLink onto stack
$push_rLink_macro;
// copy data from the port to the cbuffer
r8 = &$codec_in_copy_struc;
call $cbops.copy;
// post another timer event
r1 = &$codec_in_timer_struc;
r2 = TMR_PERIOD_CODEC_COPY;
r3 = &$codec_in_copy_handler;
call $timer.schedule_event_in_period;
// pop rLink from stack
jump $pop_rLink_and_rts;
.ENDMODULE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -