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

📄 stream.cpp

📁 GNU ccAudio2 is a stand-alone portable C++ class framework for manipulating audio data. It has exist
💻 CPP
字号:
// Copyright (C) 2004-2005 Open Source Telecom Corporation.//  // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.//// This exception applies only to the code released under the name GNU// ccAudio.  If you copy code from other releases into a copy of GNU// ccAudio, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU ccAudio, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include "private.h"#include "audio2.h"#include <cstdlib>#include <cstdio>using namespace ost;ssize_t AudioDevice::putBuffer(Encoded data, size_t count){	return 0;}ssize_t AudioDevice::getBuffer(Encoded data, size_t count){	return 0;}unsigned AudioDevice::bufMono(Linear samples, unsigned count){	unsigned fill, index;	Sample sbuf[160];	unsigned total = 0;	if(!isStereo(info.encoding))		return putSamples(samples, count);	while(count)	{		if(count < 80)			fill = count;		else			fill = 80;		for(index = 0; index < fill; ++ index)			sbuf[index * 2] = sbuf[index * 2 + 1] = samples[index];		total += putSamples(sbuf, fill * 2);		count -= fill;		samples += fill;	}	return total;}unsigned AudioDevice::bufStereo(Linear samples, unsigned count){	unsigned fill, index;	Sample mbuf[80];	unsigned total = 0;	if(isStereo(info.encoding))		return putSamples(samples, count);	while(count)	{		if(count < 80)			fill = count;		else			fill = 80;		for(index = 0; index < fill; ++ index)			mbuf[index] = samples[index * 2] / 2 +				samples[index * 2 + 1] / 2;		total += putSamples(mbuf, fill);		count -= fill;		samples += (fill * 2);	}	return total;}AudioStream::AudioStream() : AudioFile(){	codec = NULL;	framebuf = NULL;	bufferFrame = NULL;	encBuffer = NULL;	decBuffer = NULL;	encSize = decSize = 0;	bufferPosition = 0;}AudioStream::AudioStream(const char *fname, Mode m, timeout_t framing){	codec = NULL;	framebuf = NULL;	bufferFrame = NULL;	bufferPosition = 0;	open(fname, m, framing);}AudioStream::AudioStream(const char *fname, Info *info, bool exclusive, timeout_t framing){	codec = NULL;	framebuf = NULL;	bufferFrame = NULL;	bufferPosition = 0;	create(fname, info, exclusive, framing);}AudioStream::~AudioStream(){	AudioStream::close();	AudioFile::clear();}bool AudioStream::isStreamable(void){	if(!isOpen())		return false;	if(!streamable)		return false;	return true;}void AudioStream::flush(void){	unsigned pos;	if(!bufferFrame)		return;	if(bufferPosition)	{		for(pos = bufferPosition; pos < getCount() * bufferChannels; ++pos)			bufferFrame[pos] = 0;		if(bufferChannels == 1)			putMono(bufferFrame, 1);		else			putStereo(bufferFrame, 1);	}	delete[] bufferFrame;	bufferFrame = NULL;	bufferPosition = 0;}void AudioStream::close(void){	flush();	if(codec)		AudioCodec::endCodec(codec);	if(framebuf)		delete[] framebuf;	if(encBuffer)		delete[] encBuffer;	if(decBuffer)		delete[] decBuffer;	encSize = decSize = 0;	encBuffer = decBuffer = NULL;	framebuf = NULL;	codec = NULL;	AudioFile::close();}void AudioStream::create(const char *fname, Info *info, bool exclusive, timeout_t framing){	if(!framing)		framing = 20;	close();	AudioFile::create(fname, info, exclusive, framing);	if(!isOpen())		return;	streamable = true;	if(isLinear(AudioFile::info.encoding))		return;	codec = AudioCodec::getCodec(AudioFile::info, false);	if(!codec)	{		streamable = false;		return;	}	framebuf = new unsigned char[maxFramesize(AudioFile::info)];}void AudioStream::open(const char *fname, Mode m, timeout_t framing){	if(!framing)		framing = 20;	close();	AudioFile::open(fname, m, framing);	if(!isOpen())		return;	streamable = true;	if(isLinear(info.encoding))		return;	codec = AudioCodec::getCodec(info, false);	if(!codec)		streamable = false;	else		framebuf = new unsigned char[maxFramesize(info)];}unsigned AudioStream::getCount(void){	if(!isStreamable())		return 0;	return info.framecount;}unsigned AudioStream::getMono(Linear buffer, unsigned frames){	unsigned char *iobuf = (unsigned char *)buffer;	unsigned count, offset, copied = 0;	ssize_t len;	Linear dbuf = NULL;	if(!isStreamable())		return 0;	if(!frames)		++frames;	count = frames * getCount();	if(isStereo(info.encoding))		dbuf = new Sample[count * 2];	if(codec)		iobuf = framebuf;	else if(dbuf)		iobuf = (unsigned char *)dbuf;	while(frames--)	{		len = getBuffer(iobuf);	// packet read		if(len < (ssize_t)info.framesize)			break;		++copied;		if(codec)		{			codec->decode(buffer, iobuf, info.framecount);			goto stereo;		}		if(dbuf)			swapEndian(info, dbuf, info.framecount);		else			swapEndian(info, buffer, info.framecount);stereo:		if(!dbuf)		{			buffer += info.framecount;			continue;		}		for(offset = 0; offset < info.framecount; ++offset)			buffer[offset] =				dbuf[offset * 2] / 2 + dbuf[offset * 2 + 1] / 2;		buffer += info.framecount;	}	if(dbuf)		delete[] dbuf;	return copied;}unsigned AudioStream::getStereo(Linear buffer, unsigned frames){	unsigned char *iobuf = (unsigned char *)buffer;	unsigned count, offset, copied = 0;	ssize_t len;	if(!isStreamable())		return 0;		if(!frames)		++frames;	count = frames * getCount();		if(codec)		iobuf = framebuf;	while(frames--)	{		len = getBuffer(iobuf);		// packet read		if(len < (ssize_t)info.framesize)					break;		++copied;		if(codec)		{			codec->decode(buffer, iobuf, info.framecount);			goto stereo;		}		swapEndian(info, buffer, info.framecount);stereo:		if(isStereo(info.encoding))		{			buffer += (info.framecount * 2);			continue;		}		offset = info.framecount;		while(offset--)		{			buffer[offset * 2] = buffer[offset];			buffer[offset * 2 + 1] = buffer[offset];		}		buffer += (info.framecount * 2);	}	return copied;}		unsigned AudioStream::putMono(Linear buffer, unsigned frames){        Linear iobuf = buffer, dbuf = NULL;        unsigned count, offset, copied = 0;	ssize_t len;	if(!isStreamable())		return 0;	if(!frames)		++frames;	count = frames * getCount();	if(isStereo(info.encoding))	{		dbuf = new Sample[info.framecount * 2];		iobuf = dbuf;	}	while(frames--)	{		if(dbuf)		{			for(offset = 0; offset < info.framecount; ++offset)				dbuf[offset * 2] = dbuf[offset * 2 + 1] = buffer[offset];		}				if(codec)		{			codec->encode(iobuf, framebuf, info.framecount);			len = putBuffer(framebuf);			if(len < (ssize_t)info.framesize)				break;			++copied;			buffer += info.framecount;			continue;		}				swapEndian(info, iobuf, info.framecount);		len = putBuffer((Encoded)iobuf);		if(len < (ssize_t)info.framesize)			break;		++copied;		buffer += info.framecount;	}	if(dbuf)		delete[] dbuf;	return copied;}			unsigned AudioStream::putStereo(Linear buffer, unsigned frames){        Linear iobuf = buffer, mbuf = NULL;        unsigned count, offset, copied = 0;	ssize_t len;	if(!isStreamable())		return 0;        if(!frames)                ++frames;        count = frames * getCount();	if(!isStereo(info.encoding))	{		mbuf = new Sample[info.framecount];		iobuf = mbuf;	}	while(frames--)	{		if(mbuf)		{			for(offset = 0; offset < info.framecount; ++offset)				mbuf[offset] = buffer[offset * 2] / 2 + buffer[offset * 2 + 1] / 2;		}		if(codec)		{			codec->encode(iobuf, framebuf, info.framecount);			len = putBuffer(framebuf);			if(len < (ssize_t)info.framesize)				break;			++copied;			buffer += info.framecount;			continue;		}		swapEndian(info, iobuf, info.framecount);		len = putBuffer((Encoded)iobuf);		if(len < (ssize_t)info.framesize)			break;		++copied;	}	if(mbuf)		delete[] mbuf;	return copied;}unsigned AudioStream::bufMono(Linear samples, unsigned count){	unsigned size = getCount();	if(bufferChannels != 1)		flush();	if(!bufferFrame)	{		bufferFrame = new Sample[size];		bufferChannels = 1;		bufferPosition = 0;	}	return bufAudio(samples, count, size);}unsigned AudioStream::bufStereo(Linear samples, unsigned count){	unsigned size = getCount() * 2;	if(bufferChannels != 2)		flush();	if(!bufferFrame)	{		bufferFrame = new Sample[size];		bufferChannels = 2;		bufferPosition = 0;	}	return bufAudio(samples, count * 2, size);}unsigned AudioStream::bufAudio(Linear samples, unsigned count, unsigned size){	unsigned fill = 0;	unsigned frames = 0, copy, result;	if(bufferPosition)		fill = size - bufferPosition;		else if(count < size)		fill = count;	if(fill > count)		fill = count;	if(fill)	{		memcpy(&bufferFrame[bufferPosition], samples, fill * 2);		bufferPosition += fill;		samples += fill;		count -= fill;	}	if(bufferPosition == size)	{		if(bufferChannels == 1)			frames = putMono(bufferFrame, 1);		else			frames = putStereo(bufferFrame, 1);		bufferPosition = 0;		if(!frames)			return 0;	}	if(!count)		return frames;	if(count >= size)	{		copy = (count / size);		if(bufferChannels == 1)			result = putMono(samples, copy);		else			result = putStereo(samples, copy);		if(result < copy)			return frames + result;		samples += copy * size;		count -= copy * size;		frames += result;	}			if(count)	{		memcpy(bufferFrame, samples, count * 2);		bufferPosition = count;	}	return frames;}unsigned AudioStream::getEncoded(Encoded addr, unsigned frames){	unsigned count = 0, len;	if(isLinear(info.encoding))		return getMono((Linear)addr, frames);	while(frames--)	{		len = getBuffer(addr);	// packet read		if(len < info.framesize)			break;		addr += info.framesize;		++count;	}	return count;}			unsigned AudioStream::putEncoded(Encoded addr, unsigned frames){	unsigned count = 0;	ssize_t len;	if(isLinear(info.encoding))		return putMono((Linear)addr, frames);	while(frames--)	{		len = putBuffer(addr);		if(len < (ssize_t)info.framesize)			break;		addr += info.framesize;		++count;	}	return count;}			unsigned AudioStream::getEncoded(AudioCodec *codec, Encoded addr, unsigned frames){	Info ci;	unsigned count = 0;	unsigned bufsize = 0;	unsigned used = 0;	bool eof = false;	if(!codec)		return getEncoded(addr, frames);	ci = codec->getInfo();	if(ci.encoding == info.encoding && ci.framecount == info.framecount)		return getEncoded(addr, frames);	if(!isStreamable())		return 0;	while(bufsize < ci.framesize)		bufsize += info.framesize;	if(encSize != bufsize)	{		if(encBuffer)			delete[] encBuffer;		encBuffer = new Sample[bufsize];		encSize = bufsize;	}	while(count < frames && !eof)	{			while(used < ci.framesize)		{			if(getMono(encBuffer + used, 1) < 1)			{				eof = true;				break;			}			used += info.framesize;		}		codec->encode(encBuffer, addr, ci.framesize);		if(ci.framesize < used)			memcpy(encBuffer, encBuffer + ci.framesize, used - ci.framesize);		used -= ci.framesize;	}	return count;}unsigned AudioStream::putEncoded(AudioCodec *codec, Encoded addr, unsigned frames){	Info ci;	unsigned count = 0;        if(!codec)                return putEncoded(addr, frames);        ci = codec->getInfo();        if(ci.encoding == info.encoding && ci.framecount == info.framecount)                return putEncoded(addr, frames);	if(!isStreamable())		return 0;	if(ci.framecount != decSize)	{		if(decBuffer)			delete[] decBuffer;		decBuffer = new Sample[ci.framecount];		decSize = ci.framecount;	}		while(count < frames)	{		codec->decode(decBuffer, addr, ci.framecount);		if(bufMono(decBuffer, ci.framecount) < ci.framecount)			break;		++count;		addr += ci.framesize;	}        return count;}

⌨️ 快捷键说明

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