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

📄 audiofile.cpp

📁 GNU ccAudio2 is a stand-alone portable C++ class framework for manipulating audio data. It has exist
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		info.format = snd;		info.order = __BIG_ENDIAN;		header = getLong(filehdr + 4);		info.rate = getLong(filehdr + 16);		channels = getLong(filehdr + 20);		switch(getLong(filehdr + 12))		{		case 2:			if(channels > 1)				info.encoding = pcm8Stereo;			else				info.encoding = pcm8Mono;			break;		case 3:			if(info.rate == 44100)			{				if(channels > 1)					info.encoding = cdaStereo;				else					info.encoding = cdaMono;				break;			}			if(channels > 1)				info.encoding = pcm16Stereo;			else				info.encoding = pcm16Mono;			break;		case 5:			if(channels > 1)				info.encoding = pcm32Stereo;			else				info.encoding = pcm32Mono;			break;		case 23:			info.encoding = g721ADPCM;			break;		case 24:			info.encoding = g722Audio;			break;		case 25:			info.encoding = g723_3bit;			break;		case 26:			info.encoding = g723_5bit;			break;		case 27:			info.encoding = alawAudio;			break;		case 1:			info.encoding = mulawAudio;			break;		default:			info.encoding = unknownEncoding;		}		if(header > 24)		{			info.annotation = new char[header - 24];			afSeek(24);			afRead((unsigned char *)info.annotation, header - 24);		}		goto done;	}	if(!strnicmp((char *)filehdr, "ID3", 3))	{		afSeek(10);		info.order = __BIG_ENDIAN;		header = 10;		if(filehdr[5] & 0x10)			header += 10;	// footer		header += (filehdr[9] & 0x7f);		header += (filehdr[8] & 0x7f) * 128;		header += (filehdr[7] & 0x7f) * 128 * 128;		header += (filehdr[6] & 0x7f) * 128 * 128 * 128;		afSeek(header);		afRead(filehdr, 4);		goto mp3;	}			if(mp3->mp_sync1 == 0xff && mp3->mp_sync2 == 0x07)		goto mp3; 	else		afSeek(0);	goto done;mp3:	framing = 0;	afSeek(header);	info.order = __BIG_ENDIAN;	info.format = mpeg;	mp3info(mp3);	return;done:	info.headersize = 0;	if(framing)		info.setFraming(framing);	else		info.set();	if(mode == modeFeed)	{		setPosition();		iolimit = (unsigned long)toBytes(info, getPosition());		setPosition(0);	}}void AudioFile::mp3info(mpeg_audio *mp3){	info.headersize = 4;	info.padding = 0;	if(mp3->mp_pad)		info.padding = 1;	switch(mp3->mp_layer)	{	case 0x03:		if(mp3->mp_pad)			info.padding = 4;		info.encoding = mp1Audio;		break;	case 0x02:		info.encoding = mp2Audio;		break;	case 0x01:		info.encoding = mp3Audio;		break;	}	switch(mp3->mp_ver)	{	case 0x03:		info.bitrate = 32000;		switch(mp3->mp_srate)		{		case 00:			info.rate = 44100;			break;		case 01:			info.rate = 48000;			break;		case 02:			info.rate = 32000;		}		switch(mp3->mp_layer)		{		case 0x03:			info.bitrate = 32000 * mp3->mp_brate;			break;		case 0x02:			if(mp3->mp_brate < 8)				info.bitrate = 16000 * (mp3->mp_brate + 1);			else					info.bitrate = 32000 * (mp3->mp_brate - 4); 			break;		case 0x01:			switch(mp3->mp_brate)			{			case 0x02:				info.bitrate = 40000;				break;			case 0x03:				info.bitrate = 48000;				break;			case 0x04:				info.bitrate = 56000;				break;			case 0x05:				info.bitrate = 64000;				break;			case 0x06:				info.bitrate = 80000;				break;			case 0x07:				info.bitrate = 96000;				break;			case 0x08:				info.bitrate = 112000;				break;			case 0x09:				info.bitrate = 128000;				break;			case 0x0a:				info.bitrate = 160000;				break;			case 0x0b:				info.bitrate = 192000;				break;			case 0x0c:				info.bitrate = 224000;				break;			case 0x0d:				info.bitrate = 256000;				break;			case 0x0e:				info.bitrate = 320000;				break;			}			break;			}		break;	case 0x00:		switch(mp3->mp_srate)		{		case 00:			info.rate = 11025;			break;		case 01:			info.rate = 12000;			break;		case 02:			info.rate = 8000;			break;		}	case 0x02:		if(mp3->mp_ver == 0x02)		{			switch(mp3->mp_srate)			{			case 00:				info.rate = 22050;				break;			case 01:				info.rate = 24000;				break;			case 02:				info.rate = 16000;				break;			}		}		switch(mp3->mp_layer)		{		case 0x03:			if(mp3->mp_brate < 0x0d)				info.bitrate = 16000 * (mp3->mp_brate + 1);			else if(mp3->mp_brate == 0x0d)				info.bitrate = 224000;			else				info.bitrate = 256000;			break;		case 0x02:		case 0x01:			if(mp3->mp_brate < 9)				info.bitrate = 8000 * mp3->mp_brate;			else				info.bitrate = 16000 * (mp3->mp_brate - 4);		}	}	if(mp3->mp_crc)		info.headersize = 6;	info.set();}Audio::Info::Info(){	clear();}void Audio::Info::clear(void){	memset(this, 0, sizeof(Info));}void Audio::Info::setFraming(timeout_t timeout){	set();	framing = getFraming(encoding);	if(!timeout)		return;	if(framing)	{		timeout = (timeout / framing);		if(!timeout)			timeout = framing;		else			timeout = timeout * framing;	}	switch(timeout)	{	case 10:	case 15:	case 20:	case 30:	case 40:		break;	default:		timeout = 20;	}	framing = timeout;	framecount = (rate * framing) / 1000l;	framesize = (unsigned)toBytes(encoding, framecount);};void Audio::Info::set(void){	switch(encoding)	{	case mp1Audio:		framecount = 384;		framesize = (12 * bitrate / rate) * 4 + headersize + padding;		return;	case mp2Audio:	case mp3Audio:		framecount = 1152;		framesize = (144 * bitrate / rate) + headersize + padding;		return;	default:		break;	}	if(!framesize)		framesize = getFrame(encoding);	if(!framecount)		framecount = getCount(encoding);	if(!rate)		rate = getRate(encoding);	if(!bitrate && rate && framesize && framecount)		bitrate = ((long)framesize * 8l * rate) / (long)framecount;}void AudioFile::close(void){	unsigned char buf[58];	if(! isOpen())		return;	if(mode != modeWrite)	{		afClose();		return;	}	if(! afSeek(0)) {		afClose();		clear();		return;	}		if(-1 == afRead(buf, 58)) {		afClose();		clear();		return;	}	afSeek(0);	switch(info.format) {	case riff:	case wave:		// RIFF header		setLong(buf + 4, length - 8);		// If it's a non-PCM datatype, the offsets are a bit		// different for subchunk 2.		if(info.encoding < cdaStereo)			setLong(buf + 54, length - header);		else			setLong(buf + 40, length - header); 		afWrite(buf, 58);		break;	case snd:		setLong(buf + 8, length - header);		afWrite(buf, 12);		break;	default:		break;	}	afClose();	clear();}void AudioFile::clear(void){	if(pathname)	{		if(pathname)			delete[] pathname;		pathname = NULL;	}	if(info.annotation)	{		if(info.annotation)			delete[] info.annotation;		info.annotation = NULL;	}	minimum = 0;	iolimit = 0;}Audio::Error AudioFile::getInfo(Info *infobuf){	if(!isOpen())		return setError(errNotOpened);	if(!infobuf)		return setError(errRequestInvalid);	memcpy(infobuf, &info, sizeof(info));	return errSuccess;}Audio::Error AudioFile::setError(Error err){	if(err)		error = err;	return err;}const char * AudioFile::getErrorStr(Error err){	return ErrorStrs[err];}Audio::Error AudioFile::setMinimum(unsigned long samples){	if(!isOpen())		return setError(errNotOpened);	minimum = samples;	return errSuccess;}unsigned AudioFile::getLinear(Linear addr, unsigned samples){	unsigned rts = 0;	int count;	AudioCodec *codec;	if(!samples)		samples = info.framecount;	if(getEncoding() == pcm16Mono)	{		count = getNative((Encoded)addr, samples * 2);		if(count < 0)			return 0;		return count / 2;	}	codec = getCodec();	if(!codec)		return 0;	count = getCount(info.encoding);	samples = (samples / count) * count;	count = (int)toBytes(info, samples);	Encoded buffer = new unsigned char[count];	count = getBuffer(buffer, count);	if(count < 1)	{		delete[] buffer;		return 0;	}	samples = toSamples(info, count);	rts = codec->decode(addr, buffer, samples);	delete[] buffer;	return rts;}unsigned AudioFile::putLinear(Linear addr, unsigned samples){	int count;	AudioCodec *codec;	if(!samples)		samples = info.framecount;	if(getEncoding() == pcm16Mono)	{		count = putNative((Encoded)addr, samples * 2);		if(count < 0)			return 0;		return count / 2;	}	codec = getCodec();	if(!codec)		return 0;	count = getCount(info.encoding);	samples = samples / count * count;	count = (int)toBytes(info, samples);	Encoded buffer = new unsigned char[count];	samples = codec->encode(addr, buffer, samples);	if(samples < 1)	{		delete[] buffer;		return 0;	}	count = (int)toBytes(info, samples);	count = putBuffer(buffer, count);	delete[] buffer;	if(count < 0)		return 0;	return toSamples(info, count);}ssize_t AudioFile::getBuffer(Encoded addr, size_t bytes){	Info prior;	char *fname;	int count;	unsigned long curpos, xfer = 0;	mpeg_audio *mp3 = (mpeg_audio *)addr;	if(!bytes && info.format == mpeg)	{rescan:		count = afRead(addr, 4);		if(count < 0)			return count;		if(count < 4)			return 0;		if(mp3->mp_sync1 != 0xff || mp3->mp_sync2 != 0x07)		{			afSeek(getAbsolutePosition() - 3);			goto rescan;		}			mp3info(mp3);		count = afRead(addr + 4, info.framesize - 4);		if(count > 0)			count += 4;		return count;	}				if(!bytes)		bytes = info.framesize;    curpos = (unsigned long)toBytes(info, getPosition());	if(curpos >= iolimit && mode == modeFeed)	{		curpos = 0;		setPosition(0);	}        if (iolimit && ((curpos + bytes) > iolimit))                bytes = iolimit - curpos;        if (bytes < 0)                bytes = 0;	getInfo(&prior);	for(;;)	{		count = afRead(addr, (unsigned)bytes);		if(count < 0)		{			if(!xfer)				return count;			return xfer;		}		xfer += count;		if(count == (int)bytes)			return xfer;		if(mode == modeFeed)		{			setPosition(0l);			goto cont;		}retry:		if(mode == modeReadOne)			fname = NULL;		else			fname = getContinuation();		if(!fname)			return xfer;		AudioFile::close();		AudioFile::open(fname, modeRead, info.framing);		if(!isOpen())		{			if(mode == modeReadAny)				goto retry;			return xfer;		}		if(prior.encoding != info.encoding)		{			AudioFile::close();			return xfer;		}cont:		bytes -= count;		addr += count;	}}Audio::Error AudioFile::getSamples(void *addr, unsigned request){	char *fname;	unsigned char *caddr = (unsigned char *)addr;	int count, bytes;	if(!request)		request = info.framecount;	for(;;)	{		bytes = (int)toBytes(info, request);		if(bytes < 1)			return setError(errRequestInvalid);		count = afRead(caddr, bytes);		if(count == bytes)			return errSuccess;		if(count < 0)			return errReadFailure;		if(count > 0)		{			caddr += count;			count = request - toSamples(info.encoding, count);		}		else			count = request;		if(mode == modeFeed)		{			setPosition(0);			request = count;			continue;		}retry:		if(mode == modeReadOne)			fname = NULL;		else			fname = getContinuation();		if(!fname)			break;		AudioFile::close();		AudioFile::open(fname, modeRead);		if(!isOpen())		{			if(mode == modeReadAny)				goto retry;			break;		}		request = count;	}	if(count)		Audio::fill(caddr, count, info.encoding);	return errReadIncomplete;}ssize_t AudioFile::putBuffer(Encoded addr, size_t len){	int count;	unsigned long curpos;	mpeg_audio *mp3 = (mpeg_audio *)addr;	if(!len && info.format == mpeg)	{		mp3info(mp3);		len = info.framesize;	}	if(!len)		len = info.framesize;	curpos = (unsigned long)toBytes(info, getPosition());        if(curpos >= iolimit && mode == modeFeed)        {                curpos = 0;                setPosition(0);        }        if (iolimit && ((curpos + len) > iolimit))                len = iolimit - curpos;        if (len <= 0)		return 0;  	count = afWrite((unsigned char *)addr, (unsigned)len);	if(count == (int)len) {		length += count;		return count;	}	if(count < 1)		return count;	else { 		length += count;		return count;	}}Audio::Error AudioFile::putSamples(void *addr, unsigned samples){	int count;	int bytes;	if(!samples)		samples = info.framecount;	bytes = (int)toBytes(info, samples);	if(bytes < 1)		return setError(errRequestInvalid);	count = afWrite((unsigned char *)addr, bytes);	if(count == bytes) {		length += count;		return errSuccess;	}	if(count < 1)		return errWriteFailure;	else {		length += count;		return errWriteIncomplete;	}}Audio::Error AudioFile::skip(long samples){	unsigned long orig = getPosition();	unsigned long pos = orig + samples;	if(pos < 0)		pos = 0;	setPosition(pos);	if(orig < getPosition())		length += (getPosition() - orig);	return errSuccess;}Audio::Error AudioFile::setLimit(unsigned long samples){	if(!isOpen())		return setError(errNotOpened);	if(!samples)	{		iolimit = 0;		return errSuccess;	}	samples += getPosition();	iolimit = (unsigned long)toBytes(info, samples);	return errSuccess;}bool AudioFile::isSigned(void){	switch(info.format)	{	case snd:		return false;	default:		break;	}	switch(info.encoding)	{	case pcm8Mono:	case pcm8Stereo:	case pcm16Mono:	case pcm16Stereo:	case pcm32Mono:	case pcm32Stereo:		return true;	default:		return false;	}}Audio::Error AudioFile::position(const char *timestamp){	timeout_t pos = toTimeout(timestamp);	pos /= info.framing;	return setPosition(pos * info.framecount);}void AudioFile::getPosition(char *timestamp, size_t size){	timeout_t pos = getAbsolutePosition();	pos /= info.framecount;	toTimestamp(pos * info.framing, timestamp, size);}		

⌨️ 快捷键说明

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