codec_decoder.asm
来自「bc5_stereo:bluetooth stereo Headset CODE」· 汇编 代码 · 共 729 行 · 第 1/2 页
ASM
729 行
0; // Index of the input buffer to use
.ENDBLOCK;
.BLOCK $dac_mono_out_op;
.VAR $dac_mono_out_op.next = &$dac_out_mix_op_right;
.VAR $dac_mono_out_op.func = &$cbops.copy_op;
.VAR $dac_mono_out_op.param[$cbops.copy_op.STRUC_SIZE] =
0, // Input index
1; // Output index
.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;
// initialise the pskey library
call $pskey.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;
call $application_initialise;
// 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;
.ifdef FORCE_MONO
r0 = 0;
.endif
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;
// start timer that copies tone samples
r1 = &$tone_copy_timer_struc;
r2 = TMR_PERIOD_TONE_COPY;
r3 = &$tone_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;
// Upsample the tone if there is one
r8 = $tone_resample_copy_struc;
call $cbops.copy;
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;
.ifdef FORCE_MONO
r0 = 0;
.endif
if Z r8 = r7;
// Call the copy routine
call $cbops.copy;
// Copy the audio to the ports and mix in tones if necessary
r8 = &$stereo_out_mix_copy_struc;
r7 = &$mono_out_mix_copy_struc;
r0 = $AUDIO_RIGHT_OUT_PORT;
call $cbuffer.is_it_enabled;
.ifdef FORCE_MONO
r0 = 0;
.endif
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:
// $tone_copy_handler
//
// DESCRIPTION:
// Function called on a timer interrupt to perform the copying of tone
// samples.
//
// *****************************************************************************
.MODULE $M.tone_copy_handler;
.CODESEGMENT PM;
.DATASEGMENT DM;
$tone_copy_handler:
// push rLink onto stack
$push_rLink_macro;
// copy tone data from the port
r8 = &$tone_in_copy_struc;
call $cbops.copy;
// post another timer event
r1 = &$tone_copy_timer_struc;
r2 = TMR_PERIOD_TONE_COPY;
r3 = &$tone_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;
// *****************************************************************************
// MODULE:
// $application_init
//
// DESCRIPTION:
//
// *****************************************************************************
.MODULE $M.application_initialise;
.CODESEGMENT PM;
.DATASEGMENT DM;
.CONST $PSKEY_USER_38 688;
// Structure for the PSKey message handler
.VAR $audio_application_details_pskey_struc[$pskey.STRUC_SIZE];
$application_initialise:
// push rLink onto stack
$push_rLink_macro;
// Read in PSKeys and set parameters
r1 = &$audio_application_details_pskey_struc;
r2 = $PSKEY_USER_38;
r3 = &$audio_application_details_pskey_handler;
call $pskey.read_key;
// pop rLink from stack
jump $pop_rLink_and_rts;
.ENDMODULE;
.MODULE $M.audio_application_details_pskey_handler;
.CODESEGMENT PM;
.DATASEGMENT DM;
.CONST MAX_PSKEY_LENGTH 64;
.VAR/DM2 $PS_Buffer[MAX_PSKEY_LENGTH];
$audio_application_details_pskey_handler:
// push rLink onto stack
$push_rLink_macro;
// check the read worked
Null = r2 - $pskey.FAILED_READ_LENGTH;
// If it failed exit now
if Z jump $pop_rLink_and_rts;
// See if it is bigger than the max we can handle
Null = r2 - MAX_PSKEY_LENGTH;
if Z jump $pop_rLink_and_rts;
// skip over PSkey_address in the payload
I0 = r3 + 1;
r10 = r2 - 1;
// Load the start of the PSKey Buffer
I4 = &$PS_Buffer;
//r3 = r3 + 1;
//r2 = r2 - 1;
r3 = 0xFFFF;
// now copy the received PSkey data for the name
// converting from packeted words to padded bytes
//r10 = r2;
//I0 = r3;
do PS_extract_loop;
r0 = M[I0,1];
r0 = r0 AND r3;
M[I4,1] = r0;
PS_extract_loop:
// Load the start of the PSKey Buffer
I4 = &$PS_Buffer;
// Set the parameters from the values that have been read in.
r0 = M[I4,1];
// convert the 16 bit gain into a 24 bit value
r0 = r0 LSHIFT 8;
I0 = &$dac_out_mix_op + $cbops.PARAMETER_AREA_START_FIELD + $cbops.mix.MIX_VOL_FIELD;
M[I0,0] = r0;
r0 = M[I4,1];
// convert the 16 bit gain into a 24 bit value
r0 = r0 LSHIFT 8;
I0 = &$dac_out_mix_op + $cbops.PARAMETER_AREA_START_FIELD + $cbops.mix.AUDIO_VOL_FIELD;
M[I0,0] = r0;
// pop rLink from stack
jump $pop_rLink_and_rts;
.ENDMODULE;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?