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

📄 amr_file.cpp

📁 MONOGRAM AMR Splitter v0.9.0.1
💻 CPP
字号:
//-----------------------------------------------------------------------------
//
//	AMR Demuxer
//
//	Author : Igor Janos
//
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include <math.h>

const int AMR_Frame_Size[] = {
	13, 14, 16, 18, 20, 21, 27, 32,
	6, 6, 6, 6, 0, 0, 0, 1
};

//-----------------------------------------------------------------------------
//
//	CAMRFile class
//
//-----------------------------------------------------------------------------

CAMRFile::CAMRFile() :
	duration_10mhz(0),
	reader(NULL)
{
	total_samples = 0;
	current_sample = 0;
}

CAMRFile::~CAMRFile()
{
}

// I/O for AMR file
int CAMRFile::Open(CAMRReader *reader)
{
	// each AMR file must begin with 6-byte long code
	uint8		magic[6];
	uint8		magic_expected[6] = { 0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A };
	HRESULT		hr;
	int			ret;

	// keep a local copy of the reader
	this->reader = reader;
	reader->Seek(0);
	ret = reader->Read(magic, 6);				if (ret < 0) return ret;
	if (memcmp(magic, magic_expected, 6) != 0) return -1;

	seek_table.SetSize(0, 30);
	seek_table.RemoveAll();

	// now parse out all AMR frames
	total_frames = 0;
	CAMRPacket	p;
	while (true) {
		ret = p.Load(reader);
		if (ret == 0) {
			// each 16 frames a seek point
			if ((total_frames & 0x0f) == 0) {
				seek_table.Add(p.file_position);
			}
			total_frames ++;
		} else {
			break;
		}
	}

	total_samples = total_frames * 160;					// 160 samples per 20ms frame
	current_sample = 0;
	duration_10mhz = total_samples * 10000000 / 8000;	// 8KHz only

	// seek to begin
	Seek(0);

	return 0;
}

// parsing out packets
int CAMRFile::ReadAudioPacket(CAMRPacket *packet, int64 *cur_sample)
{
	// end of file ?
	if (current_sample >= total_samples) return -2;

	// load packet
	int ret = packet->Load(reader);
	if (ret < 0) return ret;

	// return sample number
	if (cur_sample) *cur_sample = current_sample;
	current_sample += 160;

	return 0;
}

int CAMRFile::Seek(int64 seek_sample)
{
	// right now we seek from the beginning
	if (seek_sample > total_samples) seek_sample = total_samples;
	if (seek_sample < 0) seek_sample = 0;

	int seek_index = (seek_sample / 160) >> 4;
	int64 seek_pos = 0;
	if (seek_index >= seek_table.GetCount()) {
		seek_pos = 6;
		seek_index = seek_table.GetCount() - 1;
		if (seek_index < 0) seek_index = 0;
	} else {
		seek_pos = seek_table[seek_index];
	}

	reader->Seek(seek_pos);
	current_sample = (seek_index * 16 * 160);
	return 0;
}


//-----------------------------------------------------------------------------
//
//	CAMRPacket
//
//-----------------------------------------------------------------------------

CAMRPacket::CAMRPacket() :
	file_position(0),
	packet_size(0)
{
}

CAMRPacket::~CAMRPacket()
{
}

int CAMRPacket::Load(CAMRReader *reader)
{
	int64	avail;
	int		ret;
	packet_size = 0;
	file_position = 0;
	tStart=0;
	tStop=0;

	reader->GetPosition(&file_position, &avail);

	// end of stream
	if (file_position >= avail) return -2;

	int		toread = min(sizeof(packet), (avail-file_position));
	ret = reader->Read(packet, toread);
	if (ret < 0) return ret;

	// zistime velkost framu
	int		type = (packet[0] >> 3) & 0x0f;
	packet_size = AMR_Frame_Size[type];
	if (packet_size == 0) return -2;		// nejaka blbost
	
	// seekneme na koniec framu
	reader->Seek(file_position + packet_size);
	return 0;
}


⌨️ 快捷键说明

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