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

📄 in_aac.c

📁 jpeg and mpeg 编解码技术源代码
💻 C
字号:

#include <windows.h>

#include "in2.h"
#include "all.h"
#include "decoder.h"
#include "port.h"
#include "audio.h"

// post this to the main window at end of file (after playback as stopped)
#define WM_WA_AAC_EOF WM_USER+2

// raw configuration
#define NCH 2
#define SAMPLERATE 44100
#define BPS 16

int binisopen = 0;

int numChannel = 2;
int Samplerate = 44100;
int Bitrate = 128000;
int avg_bitsperframe = 0;

In_Module mod; // the output module (declared near the bottom of this file)
char lastfn[MAX_PATH]; // currently playing file (used for getting info on the current file)
int file_length; // file length, in bytes
int decode_pos_ms; // current decoding position, in milliseconds
int paused; // are we paused?
int seek_needed; // if != -1, it is the point that the decode thread should seek to, in ms.
char sample_buffer[1024*NCH*(BPS/8)]; // sample buffer

HANDLE input_file=INVALID_HANDLE_VALUE; // input file handle

int killPlayThread=0;					// the kill switch for the decode thread
HANDLE play_thread_handle=INVALID_HANDLE_VALUE;	// the handle to the decode thread

DWORD WINAPI __stdcall PlayThread(void *b); // the decode thread procedure

void config(HWND hwndParent)
{
	MessageBox(hwndParent,
		"AAC files without an ADIF header must be 44100kHz\n"
		"and must be encoded using MAIN or LOW profile.\n"
		"When an ADIF header is present, configuration\n"
		"will be done automatically.",
		"Configuration",MB_OK);
}
void about(HWND hwndParent)
{
	MessageBox(hwndParent,"MBSoft AAC Player v0.2, Copyright 1999 MBSoft\nFreeware","About MBSoft AAC Player",MB_OK);
}

void init() { }

void quit() { }

int isourfile(char *fn) { return 0; } 
// used for detecting URL streams.. unused here. strncmp(fn,"http://",7) to detect HTTP streams, etc

int play(char *fn) 
{ 
	int maxlatency;
	int thread_id;
	int i;
	char adif_id[5];
	FILE *file;
	static int SampleRates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};

	aac_decode_init();

	input_file = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
		OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if (input_file == INVALID_HANDLE_VALUE) // error opening file
	{
		return 1;
	}
	file_length=GetFileSize(input_file,NULL);
	CloseHandle(input_file);

	stop_now = 0;

	// very dirty hack
	file = fopen(fn,"rb");
	for (i=0; i<LEN_ADIF_ID; i++)
		adif_id[i] = fgetc(file);
	adif_id[i] = 0;
	if (strncmp(adif_id, "ADIF", 4) == 0) {
		adif_header_present = 1;
	} else adif_header_present = 0;
	fclose(file);

	strcpy(lastfn,fn);
	paused=0;
	decode_pos_ms=0;
	seek_needed=-1;

    initio(fn);
    restarttio();

    if(!startblock())
		CommonExit(1,"2028: Error finding start of block");

	Bitrate = 128000;
	Samplerate = 44100;
	numChannel = 2;
	avg_bitsperframe = 0;

	if (adif_header_present)
	{
		Bitrate = adif_header.bitrate;
		Samplerate = SampleRates[prog_config.sampling_rate_idx];
		avg_bitsperframe = prog_config.buffer_fullness;
//		if (prog_config.front.ele_is_cpe[0]) // ???
//			numChannel = 2;
//		else numChannel = 1;
	}

	do_init();

	maxlatency = mod.outMod->Open(Samplerate,numChannel,BPS, -1,-1);
	if (maxlatency < 0) // error opening device
	{
		return 1;
	}

	// initialize vis stuff
	mod.SAVSAInit(maxlatency,Samplerate);
	mod.VSASetInfo(Samplerate,numChannel);

	mod.outMod->SetVolume(-666); // set the output plug-ins default volume

	killPlayThread = 0;
	play_thread_handle = (HANDLE) CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) PlayThread,(void *) &killPlayThread,0,&thread_id);

	return 0; 
}

void pause() { paused=1; mod.outMod->Pause(1); }
void unpause() { paused=0; mod.outMod->Pause(0); }
int ispaused() { return paused; }

void stop()
{
	if (play_thread_handle != INVALID_HANDLE_VALUE)
	{
		killPlayThread=1;
		if (WaitForSingleObject(play_thread_handle,INFINITE) == WAIT_TIMEOUT)
		{
			MessageBox(mod.hMainWindow,"error asking thread to die!\n","error killing decode thread",0);
			TerminateThread(play_thread_handle,0);
		}
		CloseHandle(play_thread_handle);
		play_thread_handle = INVALID_HANDLE_VALUE;
	}
	if (binisopen) {
		//fclose(bin);
		CloseInputFile();
		binisopen = 0;
	}
	aac_decode_free();

	mod.outMod->Close();

	mod.SAVSADeInit();
}

int getlength()
{
	return (int)((file_length/(((Bitrate*8)/1000)*BPS))*1000);
}

int getoutputtime() { 
	return decode_pos_ms+(mod.outMod->GetOutputTime()-mod.outMod->GetWrittenTime()); 
}

void setoutputtime(int time_in_ms) { 
	seek_needed=time_in_ms; 
}

void setvolume(int volume) { mod.outMod->SetVolume(volume); }
void setpan(int pan) { mod.outMod->SetPan(pan); }


int EOFfound = 0;
unsigned long bitbuf;
static unsigned int subbitbuf;
static int bitcount;
#define CHAR_BIT 8
#define BITBUFSIZ (CHAR_BIT * sizeof(bitbuf))


void fillbuf(int n, FILE *file)
{
	bitbuf <<= n;
	while (n > bitcount) {
		bitbuf |= subbitbuf << (n -= bitcount);
		subbitbuf = (unsigned char) fgetc(file);
		bitcount = CHAR_BIT;
	}
	bitbuf |= subbitbuf >> (bitcount -= n);
}

unsigned int TMPgetbits(int n, FILE *file)
{
	unsigned int x;

	x = bitbuf >> (BITBUFSIZ - n);  fillbuf(n, file);
	return x;
}


void init_getbits(FILE *file)
{
	bitbuf = 0;  subbitbuf = 0;  bitcount = 0;
	fillbuf(BITBUFSIZ, file);
}

int infoDlg(char *fn, HWND hwnd)
{
	char Info[500];
	char *strProfile;
	char adif_id[5];
	FILE *file;
	int i;
	int unused;
	int bitstream, bitrate, profile, sr_idx, srate;
	static int SampleRates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};

	file = fopen(fn,"rb");
	for (i=0; i<LEN_ADIF_ID; i++)
		adif_id[i] = fgetc(file);
	adif_id[i] = 0;

	if (strncmp(adif_id, "ADIF", 4) == 0) {
		init_getbits(file);

		/* copyright string */	
		if ((TMPgetbits(LEN_COPYRT_PRES, file)) == 1) {
			for (i=0; i<LEN_COPYRT_ID; i++)
				unused = TMPgetbits(LEN_BYTE, file); 
		}
		unused = TMPgetbits(LEN_ORIG, file);
		unused = TMPgetbits(LEN_HOME, file);
		bitstream = TMPgetbits(LEN_BS_TYPE, file);
		bitrate = TMPgetbits(LEN_BIT_RATE, file);

		/* program config elements */ 
		TMPgetbits(LEN_NUM_PCE, file);
		unused = (bitstream == 0) ? TMPgetbits(LEN_ADIF_BF, file) : 0;
		TMPgetbits(LEN_TAG, file);

		profile = TMPgetbits(LEN_PROFILE, file);
		sr_idx = TMPgetbits(LEN_SAMP_IDX, file);
		if (profile == Main_Profile)
			strProfile = "Main";
		else if (profile == LC_Profile)
			strProfile = "Low Complexity";
		else if (profile == 2 /* SSR */)
			strProfile = "SSR (unsupported)";

		srate = SampleRates[sr_idx];

		wsprintf(Info,
			"%s\n\n"
			"ADIF header info:\n"
			"Profile: %s\n"
			"Bitrate: %dbps\n"
			"Sampling rate: %dHz\n"
			"Channels: %d\n",
			fn, strProfile, bitrate, srate, 2);
		MessageBox(hwnd, Info, "AAC file info box",MB_OK);
	} else {
		wsprintf(Info,
			"%s\n\n"
			"No ADIF header found\n"
			"Assumed configuration:\n"
			"Profile: Main\n"
			"Bitrate: 128000bps\n"
			"Sampling rate: 44100Hz\n"
			"Channels: 2\n",
			fn);
		MessageBox(hwnd, Info, "AAC file info box",MB_OK);
	}

	fclose(file);

	return 0;
}

LPTSTR PathFindFileName(LPCTSTR pPath)
{
    LPCTSTR pT;

    for (pT = pPath; *pPath; pPath = CharNext(pPath)) {
        if ((pPath[0] == TEXT('\\') || pPath[0] == TEXT(':')) && pPath[1] && (pPath[1] != TEXT('\\')))
            pT = pPath + 1;
    }

    return (LPTSTR)pT;   // const -> non const
}

int getbitrate(char *fn)
{
	FILE *file;
	char adif_id[5];
	int i, unused, bitrate;

	file = fopen(fn,"rb");
	for (i=0; i<LEN_ADIF_ID; i++)
		adif_id[i] = fgetc(file);
	adif_id[i] = 0;

	if (strncmp(adif_id, "ADIF", 4) == 0) {
		init_getbits(file);

		/* copyright string */	
		if ((TMPgetbits(LEN_COPYRT_PRES, file)) == 1) {
			for (i=0; i<LEN_COPYRT_ID; i++)
				unused = TMPgetbits(LEN_BYTE, file); 
		}
		unused = TMPgetbits(LEN_ORIG, file);
		unused = TMPgetbits(LEN_HOME, file);
		unused = TMPgetbits(LEN_BS_TYPE, file);
		bitrate = TMPgetbits(LEN_BIT_RATE, file);
	} else
		bitrate = 128000;

	fclose(file);

	return bitrate;
}

void getfileinfo(char *filename, char *title, int *length_in_ms)
{
	if (!filename || !*filename)  // currently playing file
	{
		if (length_in_ms) *length_in_ms=getlength();
		if (title) 
		{
			char *p=lastfn+strlen(lastfn);
			while (*p != '\\' && p >= lastfn) p--;
			strcpy(title,++p);
			if (title[lstrlen(title)-4] == '.')
				title[lstrlen(title)-4] = '\0';
		}
	}
	else // some other file
	{
		if (length_in_ms) 
		{
			HANDLE hFile;
			*length_in_ms=-1000;
			hFile = CreateFile(filename,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
				OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
			if (hFile != INVALID_HANDLE_VALUE)
			{
				int bitrate = getbitrate(filename);
				*length_in_ms = (GetFileSize(hFile,NULL)/(((bitrate*8)/1000)*BPS))*1000;
			}
			CloseHandle(hFile);
		}
		if (title) 
		{
			char *p=filename+strlen(filename);
			while (*p != '\\' && p >= filename) p--;
			strcpy(title,++p);
			if (title[lstrlen(title)-4] == '.')
				title[lstrlen(title)-4] = '\0';
		}
	}
}

void eq_set(int on, char data[10], int preamp) 
{ 
}

DWORD WINAPI __stdcall PlayThread(void *b)
{
	int done=0;
	int framebits = 0;
	int framecount = 0;

	bno = 0;

	while (! *((int *)b) ) 
	{
		if (done)
		{
			mod.outMod->CanWrite();
			if (!mod.outMod->IsPlaying())
			{
				PostMessage(mod.hMainWindow,WM_WA_AAC_EOF,0,0);
				return 0;
			}
			Sleep(10);
		}
		else if (mod.outMod->CanWrite() >= ((1024*numChannel*2)<<(mod.dsp_isactive()?1:0)))
		{
			int l = 1024*2*numChannel;
			if (stop_now) 
			{
				done=1;
			}
			else
			{
				framebits += aac_decode_frame();
				framecount++;
				if (framecount==(int)(Samplerate/8192))
				{
					mod.SetInfo(((framebits*8)/1000)+8,Samplerate/1000,numChannel,1);
					framecount = 0;
					framebits = 0;
				}
				if ((bno > 0)&&(!stop_now)) {
					mod.SAAddPCMData(outfd->sample_buffer,numChannel,BPS,decode_pos_ms);
					mod.VSAAddPCMData(outfd->sample_buffer,numChannel,BPS,decode_pos_ms);
					decode_pos_ms+=(1024*1000)/Samplerate;
					if (mod.dsp_isactive()) l=mod.dsp_dosamples((short *)outfd->sample_buffer,l/numChannel/(BPS/8),BPS,numChannel,Samplerate)*(numChannel*(BPS/8));
					mod.outMod->Write(outfd->sample_buffer,l);
				}
				bno++;
			}
		}
		else Sleep(10);
	}
	return 0;
}

void CommonWarning(char *message)
{
	MessageBox(mod.hMainWindow,message,"Warning...",MB_OK);
}

void CommonExit(int errorcode, char *message)
{
	MessageBox(mod.hMainWindow,message,"Error...",MB_OK);
	stop_now = 1;
}

In_Module mod = 
{
	IN_VER,
	"MBSoft AAC Decoder v0.2",
	0,	// hMainWindow
	0,  // hDllInstance
	"AAC\0AAC File (*.AAC)\0"
	,
	0,	// is_seekable
	1, // uses output
	config,
	about,
	init,
	quit,
	getfileinfo,
	infoDlg,
	isourfile,
	play,
	pause,
	unpause,
	ispaused,
	stop,
	
	getlength,
	getoutputtime,
	setoutputtime,

	setvolume,
	setpan,

	0,0,0,0,0,0,0,0,0, // vis stuff


	0,0, // dsp

	eq_set,

	NULL,		// setinfo

	0 // out_mod

};

__declspec( dllexport ) In_Module * winampGetInModule2()
{
	return &mod;
}

⌨️ 快捷键说明

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