📄 sdl_audiocvt.c
字号:
/* SDL - Simple DirectMedia Layer Copyright (C) 1997-2004 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@libsdl.org*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id: SDL_audiocvt.c,v 1.2 2005/01/17 20:46:08 wmaycisco Exp $";#endif/* Functions for audio drivers to perform runtime conversion of audio format */#include <stdio.h>#include "Our_SDL_audio.h"/* Effectively mix right and left channels into a single channel */void SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format){ int i; Sint32 sample;#ifdef DEBUG_CONVERT fprintf(stderr, "Converting to mono\n");#endif switch (format&0x8018) { case AUDIO_U8: { Uint8 *src, *dst; src = cvt->buf; dst = cvt->buf; for ( i=cvt->len_cvt/2; i; --i ) { sample = src[0] + src[1]; if ( sample > 255 ) { *dst = 255; } else { *dst = sample; } src += 2; dst += 1; } } break; case AUDIO_S8: { Sint8 *src, *dst; src = (Sint8 *)cvt->buf; dst = (Sint8 *)cvt->buf; for ( i=cvt->len_cvt/2; i; --i ) { sample = src[0] + src[1]; if ( sample > 127 ) { *dst = 127; } else if ( sample < -128 ) { *dst = -128; } else { *dst = sample; } src += 2; dst += 1; } } break; case AUDIO_U16: { Uint8 *src, *dst; src = cvt->buf; dst = cvt->buf; if ( (format & 0x1000) == 0x1000 ) { for ( i=cvt->len_cvt/4; i; --i ) { sample = (Uint16)((src[0]<<8)|src[1])+ (Uint16)((src[2]<<8)|src[3]); if ( sample > 65535 ) { dst[0] = 0xFF; dst[1] = 0xFF; } else { dst[1] = (sample&0xFF); sample >>= 8; dst[0] = (sample&0xFF); } src += 4; dst += 2; } } else { for ( i=cvt->len_cvt/4; i; --i ) { sample = (Uint16)((src[1]<<8)|src[0])+ (Uint16)((src[3]<<8)|src[2]); if ( sample > 65535 ) { dst[0] = 0xFF; dst[1] = 0xFF; } else { dst[0] = (sample&0xFF); sample >>= 8; dst[1] = (sample&0xFF); } src += 4; dst += 2; } } } break; case AUDIO_S16: { Uint8 *src, *dst; src = cvt->buf; dst = cvt->buf; if ( (format & 0x1000) == 0x1000 ) { for ( i=cvt->len_cvt/4; i; --i ) { sample = (Sint16)((src[0]<<8)|src[1])+ (Sint16)((src[2]<<8)|src[3]); if ( sample > 32767 ) { dst[0] = 0x7F; dst[1] = 0xFF; } else if ( sample < -32768 ) { dst[0] = 0x80; dst[1] = 0x00; } else { dst[1] = (sample&0xFF); sample >>= 8; dst[0] = (sample&0xFF); } src += 4; dst += 2; } } else { for ( i=cvt->len_cvt/4; i; --i ) { sample = (Sint16)((src[1]<<8)|src[0])+ (Sint16)((src[3]<<8)|src[2]); if ( sample > 32767 ) { dst[1] = 0x7F; dst[0] = 0xFF; } else if ( sample < -32768 ) { dst[1] = 0x80; dst[0] = 0x00; } else { dst[0] = (sample&0xFF); sample >>= 8; dst[1] = (sample&0xFF); } src += 4; dst += 2; } } } break; } cvt->len_cvt /= 2; if ( cvt->filters[++cvt->filter_index] ) { cvt->filters[cvt->filter_index](cvt, format); }}/* Discard top 4 channels */void SDL_ConvertStrip(SDL_AudioCVT *cvt, Uint16 format){ int i; Sint32 lsample, rsample;#ifdef DEBUG_CONVERT fprintf(stderr, "Converting down to stereo\n");#endif switch (format&0x8018) { case AUDIO_U8: { Uint8 *src, *dst; src = cvt->buf; dst = cvt->buf; for ( i=cvt->len_cvt/6; i; --i ) { lsample = src[0]; rsample = src[1]; dst[0] = lsample; dst[1] = rsample; src += 6; dst += 2; } } break; case AUDIO_S8: { Sint8 *src, *dst; src = (Sint8 *)cvt->buf; dst = (Sint8 *)cvt->buf; for ( i=cvt->len_cvt/6; i; --i ) { lsample = src[0]; rsample = src[1]; dst[0] = lsample; dst[1] = rsample; src += 6; dst += 2; } } break; case AUDIO_U16: { Uint8 *src, *dst; src = cvt->buf; dst = cvt->buf; if ( (format & 0x1000) == 0x1000 ) { for ( i=cvt->len_cvt/12; i; --i ) { lsample = (Uint16)((src[0]<<8)|src[1]); rsample = (Uint16)((src[2]<<8)|src[3]); dst[1] = (lsample&0xFF); lsample >>= 8; dst[0] = (lsample&0xFF); dst[3] = (rsample&0xFF); rsample >>= 8; dst[2] = (rsample&0xFF); src += 12; dst += 4; } } else { for ( i=cvt->len_cvt/12; i; --i ) { lsample = (Uint16)((src[1]<<8)|src[0]); rsample = (Uint16)((src[3]<<8)|src[2]); dst[0] = (lsample&0xFF); lsample >>= 8; dst[1] = (lsample&0xFF); dst[2] = (rsample&0xFF); rsample >>= 8; dst[3] = (rsample&0xFF); src += 12; dst += 4; } } } break; case AUDIO_S16: { Uint8 *src, *dst; src = cvt->buf; dst = cvt->buf; if ( (format & 0x1000) == 0x1000 ) { for ( i=cvt->len_cvt/12; i; --i ) { lsample = (Sint16)((src[0]<<8)|src[1]); rsample = (Sint16)((src[2]<<8)|src[3]); dst[1] = (lsample&0xFF); lsample >>= 8; dst[0] = (lsample&0xFF); dst[3] = (rsample&0xFF); rsample >>= 8; dst[2] = (rsample&0xFF); src += 12; dst += 4; } } else { for ( i=cvt->len_cvt/12; i; --i ) { lsample = (Sint16)((src[1]<<8)|src[0]); rsample = (Sint16)((src[3]<<8)|src[2]); dst[0] = (lsample&0xFF); lsample >>= 8; dst[1] = (lsample&0xFF); dst[2] = (rsample&0xFF); rsample >>= 8; dst[3] = (rsample&0xFF); src += 12; dst += 4; } } } break; } cvt->len_cvt /= 3; if ( cvt->filters[++cvt->filter_index] ) { cvt->filters[cvt->filter_index](cvt, format); }}/* Discard top 2 channels of 6 */void SDL_ConvertStrip_2(SDL_AudioCVT *cvt, Uint16 format){ int i; Sint32 lsample, rsample;#ifdef DEBUG_CONVERT fprintf(stderr, "Converting 6 down to quad\n");#endif switch (format&0x8018) { case AUDIO_U8: { Uint8 *src, *dst; src = cvt->buf; dst = cvt->buf; for ( i=cvt->len_cvt/4; i; --i ) { lsample = src[0]; rsample = src[1]; dst[0] = lsample; dst[1] = rsample; src += 4; dst += 2; } } break; case AUDIO_S8: { Sint8 *src, *dst; src = (Sint8 *)cvt->buf; dst = (Sint8 *)cvt->buf; for ( i=cvt->len_cvt/4; i; --i ) { lsample = src[0]; rsample = src[1]; dst[0] = lsample; dst[1] = rsample; src += 4; dst += 2; } } break; case AUDIO_U16: { Uint8 *src, *dst; src = cvt->buf; dst = cvt->buf; if ( (format & 0x1000) == 0x1000 ) { for ( i=cvt->len_cvt/8; i; --i ) { lsample = (Uint16)((src[0]<<8)|src[1]); rsample = (Uint16)((src[2]<<8)|src[3]); dst[1] = (lsample&0xFF); lsample >>= 8; dst[0] = (lsample&0xFF); dst[3] = (rsample&0xFF); rsample >>= 8; dst[2] = (rsample&0xFF); src += 8; dst += 4; } } else { for ( i=cvt->len_cvt/8; i; --i ) { lsample = (Uint16)((src[1]<<8)|src[0]); rsample = (Uint16)((src[3]<<8)|src[2]); dst[0] = (lsample&0xFF); lsample >>= 8; dst[1] = (lsample&0xFF); dst[2] = (rsample&0xFF); rsample >>= 8; dst[3] = (rsample&0xFF); src += 8; dst += 4; } } } break; case AUDIO_S16: { Uint8 *src, *dst; src = cvt->buf; dst = cvt->buf; if ( (format & 0x1000) == 0x1000 ) { for ( i=cvt->len_cvt/8; i; --i ) { lsample = (Sint16)((src[0]<<8)|src[1]); rsample = (Sint16)((src[2]<<8)|src[3]); dst[1] = (lsample&0xFF); lsample >>= 8; dst[0] = (lsample&0xFF); dst[3] = (rsample&0xFF); rsample >>= 8; dst[2] = (rsample&0xFF); src += 8; dst += 4; } } else { for ( i=cvt->len_cvt/8; i; --i ) { lsample = (Sint16)((src[1]<<8)|src[0]); rsample = (Sint16)((src[3]<<8)|src[2]); dst[0] = (lsample&0xFF); lsample >>= 8; dst[1] = (lsample&0xFF); dst[2] = (rsample&0xFF); rsample >>= 8; dst[3] = (rsample&0xFF); src += 8; dst += 4; } } } break; } cvt->len_cvt /= 2; if ( cvt->filters[++cvt->filter_index] ) { cvt->filters[cvt->filter_index](cvt, format); }}/* Duplicate a mono channel to both stereo channels */void SDL_ConvertStereo(SDL_AudioCVT *cvt, Uint16 format){ int i;#ifdef DEBUG_CONVERT fprintf(stderr, "Converting to stereo\n");#endif if ( (format & 0xFF) == 16 ) { Uint16 *src, *dst; src = (Uint16 *)(cvt->buf+cvt->len_cvt); dst = (Uint16 *)(cvt->buf+cvt->len_cvt*2); for ( i=cvt->len_cvt/2; i; --i ) { dst -= 2; src -= 1; dst[0] = src[0]; dst[1] = src[0]; } } else { Uint8 *src, *dst; src = cvt->buf+cvt->len_cvt; dst = cvt->buf+cvt->len_cvt*2; for ( i=cvt->len_cvt; i; --i ) { dst -= 2; src -= 1; dst[0] = src[0]; dst[1] = src[0]; } } cvt->len_cvt *= 2; if ( cvt->filters[++cvt->filter_index] ) { cvt->filters[cvt->filter_index](cvt, format); }}/* Duplicate a stereo channel to a pseudo-5.1 stream */void SDL_ConvertSurround(SDL_AudioCVT *cvt, Uint16 format){ int i;#ifdef DEBUG_CONVERT fprintf(stderr, "Converting stereo to surround\n");#endif switch (format&0x8018) { case AUDIO_U8: { Uint8 *src, *dst, lf, rf, ce; src = (Uint8 *)(cvt->buf+cvt->len_cvt); dst = (Uint8 *)(cvt->buf+cvt->len_cvt*3); for ( i=cvt->len_cvt; i; --i ) { dst -= 6; src -= 2; lf = src[0]; rf = src[1]; ce = (lf/2) + (rf/2); dst[0] = lf; dst[1] = rf; dst[2] = lf - ce; dst[3] = rf - ce; dst[4] = ce; dst[5] = ce; } } break; case AUDIO_S8: { Sint8 *src, *dst, lf, rf, ce; src = cvt->buf+cvt->len_cvt; dst = cvt->buf+cvt->len_cvt*3; for ( i=cvt->len_cvt; i; --i ) { dst -= 6; src -= 2; lf = src[0]; rf = src[1]; ce = (lf/2) + (rf/2); dst[0] = lf; dst[1] = rf; dst[2] = lf - ce; dst[3] = rf - ce; dst[4] = ce; dst[5] = ce; } } break; case AUDIO_U16: { Uint8 *src, *dst; Uint16 lf, rf, ce, lr, rr; src = cvt->buf+cvt->len_cvt; dst = cvt->buf+cvt->len_cvt*3; if ( (format & 0x1000) == 0x1000 ) { for ( i=cvt->len_cvt/4; i; --i ) { dst -= 12; src -= 4; lf = (Uint16)((src[0]<<8)|src[1]); rf = (Uint16)((src[2]<<8)|src[3]); ce = (lf/2) + (rf/2); rr = lf - ce; lr = rf - ce;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -