diff --git a/us144mkii_capture.c b/us144mkii_capture.c index 00188ff..f595bc4 100644 --- a/us144mkii_capture.c +++ b/us144mkii_capture.c @@ -122,22 +122,20 @@ static void decode_tascam_capture_block(const u8 *src_block, s32 *dst_block) { int frame, bit; - memset(dst_block, 0, - FRAMES_PER_DECODE_BLOCK * DECODED_CHANNELS_PER_FRAME * - DECODED_SAMPLE_SIZE); - for (frame = 0; frame < FRAMES_PER_DECODE_BLOCK; ++frame) { const u8 *p_src_frame_base = src_block + frame * 64; s32 *p_dst_frame = dst_block + frame * 4; - s32 ch[4] = { 0 }; for (bit = 0; bit < 24; ++bit) { u8 byte1 = p_src_frame_base[bit]; - u8 byte2 = p_src_frame_base[bit + 32]; ch[0] = (ch[0] << 1) | (byte1 & 1); ch[2] = (ch[2] << 1) | ((byte1 >> 1) & 1); + } + + for (bit = 0; bit < 24; ++bit) { + u8 byte2 = p_src_frame_base[bit + 32]; ch[1] = (ch[1] << 1) | (byte2 & 1); ch[3] = (ch[3] << 1) | ((byte2 >> 1) & 1); diff --git a/us144mkii_pcm.c b/us144mkii_pcm.c index 0c84304..886b0c5 100644 --- a/us144mkii_pcm.c +++ b/us144mkii_pcm.c @@ -57,26 +57,44 @@ void process_playback_routing_us144mkii(struct tascam_card *tascam, size_t frames) { size_t f; - const u8 *src_12, *src_34; - u8 *dst_line, *dst_digital; + + /* + * If no routing is needed and the operation is in-place, we can + * skip everything. + */ + if (tascam->line_out_source == 0 && tascam->digital_out_source == 1 && + src_buffer == dst_buffer) + return; for (f = 0; f < frames; ++f) { - src_12 = src_buffer + f * BYTES_PER_FRAME; - src_34 = src_12 + (2 * BYTES_PER_SAMPLE); - dst_line = dst_buffer + f * BYTES_PER_FRAME; - dst_digital = dst_line + (2 * BYTES_PER_SAMPLE); + const u8 *frame_base = src_buffer + f * BYTES_PER_FRAME; + u8 *dst_frame_base = dst_buffer + f * BYTES_PER_FRAME; + + /* + * Use a temporary buffer for the source frame to prevent data + * corruption during in-place routing operations. + */ + u8 temp_src_frame[BYTES_PER_FRAME]; + const u8 *src_12; + const u8 *src_34; + + memcpy(temp_src_frame, frame_base, BYTES_PER_FRAME); + src_12 = temp_src_frame; + src_34 = temp_src_frame + (2 * BYTES_PER_SAMPLE); /* LINE OUTPUTS (ch1/2 on device) */ - if (tascam->line_out_source == 0) /* "ch1 and ch2" */ - memcpy(dst_line, src_12, 2 * BYTES_PER_SAMPLE); - else /* "ch3 and ch4" */ - memcpy(dst_line, src_34, 2 * BYTES_PER_SAMPLE); + if (tascam->line_out_source == 0) /* "Playback 1-2" */ + memcpy(dst_frame_base, src_12, 2 * BYTES_PER_SAMPLE); + else /* "Playback 3-4" */ + memcpy(dst_frame_base, src_34, 2 * BYTES_PER_SAMPLE); /* DIGITAL OUTPUTS (ch3/4 on device) */ - if (tascam->digital_out_source == 0) /* "ch1 and ch2" */ - memcpy(dst_digital, src_12, 2 * BYTES_PER_SAMPLE); - else /* "ch3 and ch4" */ - memcpy(dst_digital, src_34, 2 * BYTES_PER_SAMPLE); + if (tascam->digital_out_source == 0) /* "Playback 1-2" */ + memcpy(dst_frame_base + (2 * BYTES_PER_SAMPLE), src_12, + 2 * BYTES_PER_SAMPLE); + else /* "Playback 3-4" */ + memcpy(dst_frame_base + (2 * BYTES_PER_SAMPLE), src_34, + 2 * BYTES_PER_SAMPLE); } }