⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_wave.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  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$";#endif#ifndef DISABLE_FILE/* Microsoft WAVE file loading routines */#include <stdlib.h>#include <string.h>#include "SDL_error.h"#include "SDL_audio.h"#include "SDL_wave.h"#include "SDL_endian.h"#ifndef NELEMS#define NELEMS(array)	((sizeof array)/(sizeof array[0]))#endifstatic int ReadChunk(SDL_RWops *src, Chunk *chunk);struct MS_ADPCM_decodestate {	Uint8 hPredictor;	Uint16 iDelta;	Sint16 iSamp1;	Sint16 iSamp2;};static struct MS_ADPCM_decoder {	WaveFMT wavefmt;	Uint16 wSamplesPerBlock;	Uint16 wNumCoef;	Sint16 aCoeff[7][2];	/* * * */	struct MS_ADPCM_decodestate state[2];} MS_ADPCM_state;static int InitMS_ADPCM(WaveFMT *format){	Uint8 *rogue_feel;	Uint16 extra_info;	int i;	/* Set the rogue pointer to the MS_ADPCM specific data */	MS_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);	MS_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);	MS_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);	MS_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate);	MS_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign);	MS_ADPCM_state.wavefmt.bitspersample =					 SDL_SwapLE16(format->bitspersample);	rogue_feel = (Uint8 *)format+sizeof(*format);	if ( sizeof(*format) == 16 ) {		extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]);		rogue_feel += sizeof(Uint16);	}	MS_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);	rogue_feel += sizeof(Uint16);	MS_ADPCM_state.wNumCoef = ((rogue_feel[1]<<8)|rogue_feel[0]);	rogue_feel += sizeof(Uint16);	if ( MS_ADPCM_state.wNumCoef != 7 ) {		SDL_SetError("Unknown set of MS_ADPCM coefficients");		return(-1);	}	for ( i=0; i<MS_ADPCM_state.wNumCoef; ++i ) {		MS_ADPCM_state.aCoeff[i][0] = ((rogue_feel[1]<<8)|rogue_feel[0]);		rogue_feel += sizeof(Uint16);		MS_ADPCM_state.aCoeff[i][1] = ((rogue_feel[1]<<8)|rogue_feel[0]);		rogue_feel += sizeof(Uint16);	}	return(0);}static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,					Uint8 nybble, Sint16 *coeff){	const Sint32 max_audioval = ((1<<(16-1))-1);	const Sint32 min_audioval = -(1<<(16-1));	const Sint32 adaptive[] = {		230, 230, 230, 230, 307, 409, 512, 614,		768, 614, 512, 409, 307, 230, 230, 230	};	Sint32 new_sample, delta;	new_sample = ((state->iSamp1 * coeff[0]) +		      (state->iSamp2 * coeff[1]))/256;	if ( nybble & 0x08 ) {		new_sample += state->iDelta * (nybble-0x10);	} else {		new_sample += state->iDelta * nybble;	}	if ( new_sample < min_audioval ) {		new_sample = min_audioval;	} else	if ( new_sample > max_audioval ) {		new_sample = max_audioval;	}	delta = ((Sint32)state->iDelta * adaptive[nybble])/256;	if ( delta < 16 ) {		delta = 16;	}	state->iDelta = delta;	state->iSamp2 = state->iSamp1;	state->iSamp1 = new_sample;	return(new_sample);}static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len){	struct MS_ADPCM_decodestate *state[2];	Uint8 *freeable, *encoded, *decoded;	Sint32 encoded_len, samplesleft;	Sint8 nybble, stereo;	Sint16 *coeff[2];	Sint32 new_sample;	/* Allocate the proper sized output buffer */	encoded_len = *audio_len;	encoded = *audio_buf;	freeable = *audio_buf;	*audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) * 				MS_ADPCM_state.wSamplesPerBlock*				MS_ADPCM_state.wavefmt.channels*sizeof(Sint16);	*audio_buf = (Uint8 *)malloc(*audio_len);	if ( *audio_buf == NULL ) {		SDL_Error(SDL_ENOMEM);		return(-1);	}	decoded = *audio_buf;	/* Get ready... Go! */	stereo = (MS_ADPCM_state.wavefmt.channels == 2);	state[0] = &MS_ADPCM_state.state[0];	state[1] = &MS_ADPCM_state.state[stereo];	while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) {		/* Grab the initial information for this block */		state[0]->hPredictor = *encoded++;		if ( stereo ) {			state[1]->hPredictor = *encoded++;		}		state[0]->iDelta = ((encoded[1]<<8)|encoded[0]);		encoded += sizeof(Sint16);		if ( stereo ) {			state[1]->iDelta = ((encoded[1]<<8)|encoded[0]);			encoded += sizeof(Sint16);		}		state[0]->iSamp1 = ((encoded[1]<<8)|encoded[0]);		encoded += sizeof(Sint16);		if ( stereo ) {			state[1]->iSamp1 = ((encoded[1]<<8)|encoded[0]);			encoded += sizeof(Sint16);		}		state[0]->iSamp2 = ((encoded[1]<<8)|encoded[0]);		encoded += sizeof(Sint16);		if ( stereo ) {			state[1]->iSamp2 = ((encoded[1]<<8)|encoded[0]);			encoded += sizeof(Sint16);		}		coeff[0] = MS_ADPCM_state.aCoeff[state[0]->hPredictor];		coeff[1] = MS_ADPCM_state.aCoeff[state[1]->hPredictor];		/* Store the two initial samples we start with */		decoded[0] = state[0]->iSamp2&0xFF;		decoded[1] = state[0]->iSamp2>>8;		decoded += 2;		if ( stereo ) {			decoded[0] = state[1]->iSamp2&0xFF;			decoded[1] = state[1]->iSamp2>>8;			decoded += 2;		}		decoded[0] = state[0]->iSamp1&0xFF;		decoded[1] = state[0]->iSamp1>>8;		decoded += 2;		if ( stereo ) {			decoded[0] = state[1]->iSamp1&0xFF;			decoded[1] = state[1]->iSamp1>>8;			decoded += 2;		}		/* Decode and store the other samples in this block */		samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)*					MS_ADPCM_state.wavefmt.channels;		while ( samplesleft > 0 ) {			nybble = (*encoded)>>4;			new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]);			decoded[0] = new_sample&0xFF;			new_sample >>= 8;			decoded[1] = new_sample&0xFF;			decoded += 2;			nybble = (*encoded)&0x0F;			new_sample = MS_ADPCM_nibble(state[1],nybble,coeff[1]);			decoded[0] = new_sample&0xFF;			new_sample >>= 8;			decoded[1] = new_sample&0xFF;			decoded += 2;			++encoded;			samplesleft -= 2;		}		encoded_len -= MS_ADPCM_state.wavefmt.blockalign;	}	free(freeable);	return(0);}struct IMA_ADPCM_decodestate {	Sint32 sample;	Sint8 index;};static struct IMA_ADPCM_decoder {	WaveFMT wavefmt;	Uint16 wSamplesPerBlock;	/* * * */	struct IMA_ADPCM_decodestate state[2];} IMA_ADPCM_state;static int InitIMA_ADPCM(WaveFMT *format){	Uint8 *rogue_feel;	Uint16 extra_info;	/* Set the rogue pointer to the IMA_ADPCM specific data */	IMA_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);	IMA_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);	IMA_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);	IMA_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate);	IMA_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign);	IMA_ADPCM_state.wavefmt.bitspersample =					 SDL_SwapLE16(format->bitspersample);	rogue_feel = (Uint8 *)format+sizeof(*format);	if ( sizeof(*format) == 16 ) {		extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]);		rogue_feel += sizeof(Uint16);	}	IMA_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);	return(0);}static Sint32 IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state,Uint8 nybble){	const Sint32 max_audioval = ((1<<(16-1))-1);	const Sint32 min_audioval = -(1<<(16-1));	const int index_table[16] = {		-1, -1, -1, -1,		 2,  4,  6,  8,		-1, -1, -1, -1,		 2,  4,  6,  8	};	const Sint32 step_table[89] = {		7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,		34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130,		143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408,		449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282,		1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,		3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630,		9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350,		22385, 24623, 27086, 29794, 32767	};	Sint32 delta, step;	/* Compute difference and new sample value */	step = step_table[state->index];	delta = step >> 3;	if ( nybble & 0x04 ) delta += step;	if ( nybble & 0x02 ) delta += (step >> 1);	if ( nybble & 0x01 ) delta += (step >> 2);	if ( nybble & 0x08 ) delta = -delta;	state->sample += delta;	/* Update index value */	state->index += index_table[nybble];	if ( state->index > 88 ) {		state->index = 88;	} else	if ( state->index < 0 ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -