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

📄 sdl_wave.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		state->index = 0;	}	/* Clamp output sample */	if ( state->sample > max_audioval ) {		state->sample = max_audioval;	} else	if ( state->sample < min_audioval ) {		state->sample = min_audioval;	}	return(state->sample);}/* Fill the decode buffer with a channel block of data (8 samples) */static void Fill_IMA_ADPCM_block(Uint8 *decoded, Uint8 *encoded,	int channel, int numchannels, struct IMA_ADPCM_decodestate *state){	int i;	Sint8 nybble;	Sint32 new_sample;	decoded += (channel * 2);	for ( i=0; i<4; ++i ) {		nybble = (*encoded)&0x0F;		new_sample = IMA_ADPCM_nibble(state, nybble);		decoded[0] = new_sample&0xFF;		new_sample >>= 8;		decoded[1] = new_sample&0xFF;		decoded += 2 * numchannels;		nybble = (*encoded)>>4;		new_sample = IMA_ADPCM_nibble(state, nybble);		decoded[0] = new_sample&0xFF;		new_sample >>= 8;		decoded[1] = new_sample&0xFF;		decoded += 2 * numchannels;		++encoded;	}}static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len){	struct IMA_ADPCM_decodestate *state;	Uint8 *freeable, *encoded, *decoded;	Sint32 encoded_len, samplesleft;	int c, channels;	/* Check to make sure we have enough variables in the state array */	channels = IMA_ADPCM_state.wavefmt.channels;	if ( channels > NELEMS(IMA_ADPCM_state.state) ) {		SDL_SetError("IMA ADPCM decoder can only handle %d channels",						NELEMS(IMA_ADPCM_state.state));		return(-1);	}	state = IMA_ADPCM_state.state;	/* Allocate the proper sized output buffer */	encoded_len = *audio_len;	encoded = *audio_buf;	freeable = *audio_buf;	*audio_len = (encoded_len/IMA_ADPCM_state.wavefmt.blockalign) * 				IMA_ADPCM_state.wSamplesPerBlock*				IMA_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! */	while ( encoded_len >= IMA_ADPCM_state.wavefmt.blockalign ) {		/* Grab the initial information for this block */		for ( c=0; c<channels; ++c ) {			/* Fill the state information for this block */			state[c].sample = ((encoded[1]<<8)|encoded[0]);			encoded += 2;			if ( state[c].sample & 0x8000 ) {				state[c].sample -= 0x10000;			}			state[c].index = *encoded++;			/* Reserved byte in buffer header, should be 0 */			if ( *encoded++ != 0 ) {				/* Uh oh, corrupt data?  Buggy code? */;			}			/* Store the initial sample we start with */			decoded[0] = state[c].sample&0xFF;			decoded[1] = state[c].sample>>8;			decoded += 2;		}		/* Decode and store the other samples in this block */		samplesleft = (IMA_ADPCM_state.wSamplesPerBlock-1)*channels;		while ( samplesleft > 0 ) {			for ( c=0; c<channels; ++c ) {				Fill_IMA_ADPCM_block(decoded, encoded,						c, channels, &state[c]);				encoded += 4;				samplesleft -= 8;			}			decoded += (channels * 8 * 2);		}		encoded_len -= IMA_ADPCM_state.wavefmt.blockalign;	}	free(freeable);	return(0);}SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc,		SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len){	int was_error;	Chunk chunk;	int lenread;	int MS_ADPCM_encoded, IMA_ADPCM_encoded;	int samplesize;	/* WAV magic header */	Uint32 RIFFchunk;	Uint32 wavelen;	Uint32 WAVEmagic;	/* FMT chunk */	WaveFMT *format = NULL;	/* Make sure we are passed a valid data source */	was_error = 0;	if ( src == NULL ) {		was_error = 1;		goto done;	}			/* Check the magic header */	RIFFchunk	= SDL_ReadLE32(src);	wavelen		= SDL_ReadLE32(src);	if ( wavelen == WAVE ) { /* The RIFFchunk has already been read */		WAVEmagic = wavelen;		wavelen   = RIFFchunk;		RIFFchunk = RIFF;	} else {		WAVEmagic = SDL_ReadLE32(src);	}	if ( (RIFFchunk != RIFF) || (WAVEmagic != WAVE) ) {		SDL_SetError("Unrecognized file type (not WAVE)");		was_error = 1;		goto done;	}	/* Read the audio data format chunk */	chunk.data = NULL;	do {		if ( chunk.data != NULL ) {			free(chunk.data);		}		lenread = ReadChunk(src, &chunk);		if ( lenread < 0 ) {			was_error = 1;			goto done;		}	} while ( (chunk.magic == FACT) || (chunk.magic == LIST) );	/* Decode the audio data format */	format = (WaveFMT *)chunk.data;	if ( chunk.magic != FMT ) {		SDL_SetError("Complex WAVE files not supported");		was_error = 1;		goto done;	}	MS_ADPCM_encoded = IMA_ADPCM_encoded = 0;	switch (SDL_SwapLE16(format->encoding)) {		case PCM_CODE:			/* We can understand this */			break;		case MS_ADPCM_CODE:			/* Try to understand this */			if ( InitMS_ADPCM(format) < 0 ) {				was_error = 1;				goto done;			}			MS_ADPCM_encoded = 1;			break;		case IMA_ADPCM_CODE:			/* Try to understand this */			if ( InitIMA_ADPCM(format) < 0 ) {				was_error = 1;				goto done;			}			IMA_ADPCM_encoded = 1;			break;		default:			SDL_SetError("Unknown WAVE data format: 0x%.4x",					SDL_SwapLE16(format->encoding));			was_error = 1;			goto done;	}	memset(spec, 0, (sizeof *spec));	spec->freq = SDL_SwapLE32(format->frequency);	switch (SDL_SwapLE16(format->bitspersample)) {		case 4:			if ( MS_ADPCM_encoded || IMA_ADPCM_encoded ) {				spec->format = AUDIO_S16;			} else {				was_error = 1;			}			break;		case 8:			spec->format = AUDIO_U8;			break;		case 16:			spec->format = AUDIO_S16;			break;		default:			was_error = 1;			break;	}	if ( was_error ) {		SDL_SetError("Unknown %d-bit PCM data format",			SDL_SwapLE16(format->bitspersample));		goto done;	}	spec->channels = (Uint8)SDL_SwapLE16(format->channels);	spec->samples = 4096;		/* Good default buffer size */	/* Read the audio data chunk */	*audio_buf = NULL;	do {		if ( *audio_buf != NULL ) {			free(*audio_buf);		}		lenread = ReadChunk(src, &chunk);		if ( lenread < 0 ) {			was_error = 1;			goto done;		}		*audio_len = lenread;		*audio_buf = chunk.data;	} while ( chunk.magic != DATA );	if ( MS_ADPCM_encoded ) {		if ( MS_ADPCM_decode(audio_buf, audio_len) < 0 ) {			was_error = 1;			goto done;		}	}	if ( IMA_ADPCM_encoded ) {		if ( IMA_ADPCM_decode(audio_buf, audio_len) < 0 ) {			was_error = 1;			goto done;		}	}	/* Don't return a buffer that isn't a multiple of samplesize */	samplesize = ((spec->format & 0xFF)/8)*spec->channels;	*audio_len &= ~(samplesize-1);done:	if ( format != NULL ) {		free(format);	}	if ( freesrc && src ) {		SDL_RWclose(src);	}	if ( was_error ) {		spec = NULL;	}	return(spec);}/* Since the WAV memory is allocated in the shared library, it must also   be freed here.  (Necessary under Win32, VC++) */void SDL_FreeWAV(Uint8 *audio_buf){	if ( audio_buf != NULL ) {		free(audio_buf);	}}static int ReadChunk(SDL_RWops *src, Chunk *chunk){	chunk->magic	= SDL_ReadLE32(src);	chunk->length	= SDL_ReadLE32(src);	chunk->data = (Uint8 *)malloc(chunk->length);	if ( chunk->data == NULL ) {		SDL_Error(SDL_ENOMEM);		return(-1);	}	if ( SDL_RWread(src, chunk->data, chunk->length, 1) != 1 ) {		SDL_Error(SDL_EFREAD);		free(chunk->data);		return(-1);	}	return(chunk->length);}#endif /* ENABLE_FILE */

⌨️ 快捷键说明

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