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

📄 mpeg_audio.c

📁 由bmp生成mpeg2 的I_frame 数据
💻 C
字号:
/*******************************************************************
                   MPEG Audio stream decode module
 *******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MPEG_AUDIO_C
#include "mpeg_audio.h"

MPEG_AUDIO *open_mpeg_audio(char *path);
void close_mpeg_audio(MPEG_AUDIO *p);
int read_mpeg_audio(MPEG_AUDIO *p, __int64 offset, void *buffer, int length);

MPEG_AUDIO *open_mpeg_audio(char *path)
{
	AUDIO_INFO info;
	MPEG_AUDIO *r;

	r = (MPEG_AUDIO *)malloc(sizeof(MPEG_AUDIO));
	if(r == NULL){
		return r;
	}

	r->as = audio_stream_open(path);
	if(r->as == NULL){
		free(r);
		return NULL;
	}

	r->as->get_info(r->as->stream, &info);

	r->sample = info.sample;
	r->frequency = info.frequency;
	r->channel = info.channel;

	init_pcm_buffer(&(r->pcm));
	init_layer2_work(&(r->work));
	
	InitializeCriticalSection(&(r->lock));

	return r;
}

void close_mpeg_audio(MPEG_AUDIO *p)
{
	release_pcm_buffer(&(p->pcm));
	p->as->close(p->as);
	
	DeleteCriticalSection(&(p->lock));

	free(p);
}

int read_mpeg_audio(MPEG_AUDIO *p, __int64 offset, void *buffer, int length)
{
	__int64 head;

	PCM_BUFFER_ELEMENT *elem;
	
	int r,n;
	short *pos;
	unsigned int sync;

	LAYER2_HEADER layer2;

	r = 0;
	pos = (short *)buffer;

	__asm {emms};
	
	EnterCriticalSection(&(p->lock));

	memset(buffer, 0, sizeof(short)*2*length);

	if(!find_sample_pcm_buffer(&(p->pcm), offset)){
		if(p->as->tell(p->as->stream) == offset){
			sync = p->as->next_sync(p->as->stream);
			parse_layer2_header(sync, &layer2);
			elem = new_pcm_buffer_element(offset, 1152, sizeof(short)*(p->channel));
			if(elem){
				n = p->as->read(p->as->stream, p->unit, layer2.framesize);
				if(n != layer2.framesize){
					goto READ_MPEG_AUDIO_END;
				}
				decode_layer2(&layer2, p->unit+4, &(p->work), (short *)(elem->sample));
				add_element_pcm_buffer(&(p->pcm), elem);
			}else{
				goto READ_MPEG_AUDIO_END;
			}
		}else{
			release_pcm_buffer(&(p->pcm));
			head = p->as->seek(p->as->stream, offset);
			init_layer2_work(&(p->work));
			sync = p->as->next_sync(p->as->stream);
			parse_layer2_header(sync, &layer2);
			elem = new_pcm_buffer_element(head, 1152, sizeof(short)*(p->channel));
			if(elem){
				n = p->as->read(p->as->stream, p->unit, layer2.framesize);
				if(n != layer2.framesize){
					goto READ_MPEG_AUDIO_END;
				}
				decode_layer2(&layer2, p->unit+4, &(p->work), (short *)(elem->sample));
				if(offset >= 1152){
					elem->offset += 1152;
					elem->length = 0;
				}
				add_element_pcm_buffer(&(p->pcm), elem);
			}else{
				goto READ_MPEG_AUDIO_END;
			}
		}
	}

	while(length){
		n = read_sample_pcm_buffer(&(p->pcm), offset, pos, length);
		pos += p->channel * n;
		r += n;
		length -= n;
		offset += n;
		if(length){
			sync = p->as->next_sync(p->as->stream);
			parse_layer2_header(sync, &layer2);
			elem = new_pcm_buffer_element(p->pcm.tail->offset+p->pcm.tail->length, 1152, sizeof(short)*(p->channel));
			if(elem){
				n = p->as->read(p->as->stream, p->unit, layer2.framesize);
				if(n != layer2.framesize){
					goto READ_MPEG_AUDIO_END;
				}
				decode_layer2(&layer2, p->unit+4, &(p->work), (short *)(elem->sample));
				add_element_pcm_buffer(&(p->pcm), elem);
			}else{
				goto READ_MPEG_AUDIO_END;
			}
		}
	}

READ_MPEG_AUDIO_END:
	LeaveCriticalSection(&(p->lock));
	return r;
}

⌨️ 快捷键说明

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