📄 downmix.c
字号:
/* <LIC_AMD_STD> * Copyright (C) 2003-2005 Advanced Micro Devices, Inc. All Rights Reserved. * * Unless otherwise designated in writing, this software and any related * documentation are the confidential proprietary information of AMD. * THESE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY * UNLESS OTHERWISE NOTED IN WRITING, EXPRESS OR IMPLIED WARRANTY OF ANY * KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, * NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE AND IN NO * EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER. * * AMD does not assume any responsibility for any errors which may appear * in the Materials nor any responsibility to support or update the * Materials. AMD retains the right to modify the Materials at any time, * without notice, and is not obligated to provide such modified * Materials to you. AMD is not obligated to furnish, support, or make * any further information available to you. * </LIC_AMD_STD> *//* <CTL_AMD_STD> * </CTL_AMD_STD> *//* <DOC_AMD_STD> * Filename: downmix.c * </DOC_AMD_STD> */#ifdef POSTPROC_DOWNMIX#include <stdio.h>#include <string.h>#include <stdlib.h>#include "mai_types.h"#include "../audio_out.h" #include "downmix.h" #define DPRINTF(_args_) /* printf _args_ */#define INFO_PRINTF(_args_) /* printf _args_ */#if defined(WIN32) || defined(UNDER_CE) #if _MSC_VER typedef signed __int64 int64_t; #else typedef signed long long int64_t; #endif#endif#define FRAC_ONE (1 << FRAC_BITS)#define FIX(a) ((int)((a) * FRAC_ONE))#define FRAC_BITS 23 /* fractional bits for sb_samples and dct */#define MULL(a,b) ((int)(((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS))static short *downmix_buffer;static char *downmix_input_buffer;int open_downmix(int buffer_max_size, int number_of_channels){ if (downmix_buffer != NULL) free(downmix_buffer); if ((downmix_buffer = (short *)malloc(buffer_max_size * sizeof(short) * number_of_channels)) == NULL) { DPRINTF(("Unable to allocate downmix buffer\n")); return -1; } if (downmix_input_buffer != NULL) free(downmix_input_buffer); if ((downmix_input_buffer = (char *)malloc(buffer_max_size * sizeof(short) * number_of_channels)) == NULL) { DPRINTF(("Unable to allocate downmix input buffer\n")); return -1; } INFO_PRINTF(("Downmix %d to 2\n", undownmixed_number_of_channels)); return 0;}short *downmix_to_stereo(short *buf, int *length /* in bytes */) // assumes 16 bits per sample FIXIT{ int ii, used; int ch_length = *length / (undownmixed_number_of_channels * sizeof(short)); int input_length = *length; static int remaining_bytes = 0; if (remaining_bytes) { memcpy(downmix_input_buffer+remaining_bytes, buf, *length); *length += remaining_bytes; remaining_bytes = 0; ch_length = *length / (undownmixed_number_of_channels * 2); input_length = *length; buf = (short *)downmix_input_buffer; } ch_length &= 0xfffff8; /* align to block */ switch (undownmixed_number_of_channels) { case 3: /* LF, CF, RF */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[3*ii], FIX(.5)) + MULL(buf[3*ii+1], FIX(.5)); downmix_buffer[2*ii + 1] = MULL(buf[3*ii+2], FIX(.5)) + MULL(buf[3*ii+1], FIX(.5)); } break; case 4: /* LF, RF, LR, RR */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[4*ii], FIX(.7)) + MULL(buf[4*ii+2], FIX(.4)); downmix_buffer[2*ii + 1] = MULL(buf[4*ii+1], FIX(.7)) + MULL(buf[4*ii+3], FIX(.4)); } break; case 5: /* LF, CF, RF, LR, RR */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[5*ii], FIX(.5)) + MULL(buf[5*ii+2], FIX(.4)) + MULL(buf[5*ii+1], FIX(.5)); downmix_buffer[2*ii + 1] = MULL(buf[5*ii+2], FIX(.5)) + MULL(buf[5*ii+4], FIX(.4)) + MULL(buf[5*ii+1], FIX(.5)); } break; case 6: /* LF, CF, RF, LR, RR, LFE Dolby's order is also used by AAC */ /* 0 1 2 3 4 5 */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[6*ii], FIX(.5)) - MULL(buf[6*ii+3], FIX(.4)) + MULL(buf[6*ii+1], FIX(.5)) + MULL(buf[6*ii+5], FIX(.2)); downmix_buffer[2*ii + 1] = MULL(buf[6*ii+2], FIX(.5)) - MULL(buf[6*ii+4], FIX(.4)) + MULL(buf[6*ii+1], FIX(.5)) + MULL(buf[6*ii+5], FIX(.2)); } break; case 7: /* LF, CF, RF, LR, RR, LFE, CR FIXIT this order may not be right */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[7*ii], FIX(.5)) + MULL(buf[7*ii+2], FIX(.4)) + MULL(buf[7*ii+1], FIX(.5)) + MULL(buf[7*ii+5], FIX(.2)) + MULL(buf[7*ii+6], FIX(.3)); downmix_buffer[2*ii + 1] = MULL(buf[7*ii+2], FIX(.5)) + MULL(buf[7*ii+4], FIX(.4)) + MULL(buf[7*ii+1], FIX(.5)) + MULL(buf[7*ii+5], FIX(.2)) + MULL(buf[7*ii+6], FIX(.3)); } break; case 8: /* LF, RF, CF, LFE, LR, RR, LS, RS */ /* AVI files do this. See: http://www.microsoft.com/windows/windowsmedia/howto/articles/creating71audio.aspx 0 Front left 1 Front right 2 Front center 3 Low frequency 4 Back left 5 Back right 6 Side left 7 Side right */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[7*ii], FIX(.5)) + MULL(buf[7*ii+2], FIX(.5)) + MULL(buf[7*ii+3], FIX(.2)) - MULL(buf[7*ii+4], FIX(.2)) + MULL(buf[7*ii+6], FIX(.3)); downmix_buffer[2*ii + 1] = MULL(buf[7*ii+1], FIX(.5)) + MULL(buf[7*ii+2], FIX(.5)) + MULL(buf[7*ii+3], FIX(.2)) - MULL(buf[7*ii+5], FIX(.2)) + MULL(buf[7*ii+7], FIX(.3)); } break; default: remaining_bytes = 0; return buf; } used = (ch_length * undownmixed_number_of_channels * sizeof(short)); remaining_bytes = input_length - used; memcpy(downmix_input_buffer, ((char *)buf) + input_length - remaining_bytes, remaining_bytes); *length = (ch_length * 2 /* channels */ * sizeof(short)); return downmix_buffer;}void close_downmix(void){ if (downmix_buffer != NULL) free(downmix_buffer); downmix_buffer = NULL; if (downmix_input_buffer != NULL) free(downmix_input_buffer); downmix_input_buffer = NULL;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -