コード例 #1
0
float* AUD_readSoundBuffer(const char* filename, float low, float high,
						   float attack, float release, float threshold,
						   int accumulate, int additive, int square,
						   float sthreshold, double samplerate, int* length)
{
	AUD_Buffer buffer;
	AUD_DeviceSpecs specs;
	specs.channels = AUD_CHANNELS_MONO;
	specs.rate = (AUD_SampleRate)samplerate;
	AUD_Reference<AUD_IFactory> sound;

	AUD_Reference<AUD_IFactory> file = new AUD_FileFactory(filename);

	AUD_Reference<AUD_IReader> reader = file->createReader();
	AUD_SampleRate rate = reader->getSpecs().rate;

	sound = new AUD_ChannelMapperFactory(file, specs);

	if(high < rate)
		sound = new AUD_LowpassFactory(sound, high);
	if(low > 0)
		sound = new AUD_HighpassFactory(sound, low);

	sound = new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f);
	sound = new AUD_LinearResampleFactory(sound, specs);

	if(square)
		sound = new AUD_SquareFactory(sound, sthreshold);

	if(accumulate)
		sound = new AUD_AccumulatorFactory(sound, additive);
	else if(additive)
		sound = new AUD_SumFactory(sound);

	reader = sound->createReader();

	if(reader.isNull())
		return NULL;

	int len;
	int position = 0;
	bool eos;
	do
	{
		len = samplerate;
		buffer.resize((position + len) * sizeof(float), true);
		reader->read(len, eos, buffer.getBuffer() + position);
		position += len;
	} while(!eos);

	float* result = (float*)malloc(position * sizeof(float));
	memcpy(result, buffer.getBuffer(), position * sizeof(float));
	*length = position;
	return result;
}
コード例 #2
0
int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length, int samples_per_second)
{
	AUD_DeviceSpecs specs;
	sample_t* buf;
	AUD_Buffer aBuffer;

	specs.rate = AUD_RATE_INVALID;
	specs.channels = AUD_CHANNELS_MONO;
	specs.format = AUD_FORMAT_INVALID;

	AUD_Reference<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();

	specs.specs = reader->getSpecs();
	int len;
	float samplejump = specs.rate / samples_per_second;
	float min, max, power;
	bool eos;

	for(int i = 0; i < length; i++)
	{
		len = floor(samplejump * (i+1)) - floor(samplejump * i);

		aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
		buf = aBuffer.getBuffer();

		reader->read(len, eos, buf);

		max = min = *buf;
		power = *buf * *buf;
		for(int j = 1; j < len; j++)
		{
			if(buf[j] < min)
				min = buf[j];
			if(buf[j] > max)
				max = buf[j];
			power += buf[j] * buf[j];
		}

		buffer[i * 3] = min;
		buffer[i * 3 + 1] = max;
		buffer[i * 3 + 2] = sqrt(power) / len;

		if(eos)
		{
			length = i;
			break;
		}
	}

	return length;
}
コード例 #3
0
ファイル: AUD_FFMPEGReader.cpp プロジェクト: mik0001/Blender
int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer)
{
	// save packet parameters
	uint8_t *audio_pkg_data = packet->data;
	int audio_pkg_size = packet->size;

	int buf_size = buffer.getSize();
	int buf_pos = 0;

	int read_length, data_size;

	AVPacket tmp_pkt;
	
	av_init_packet(&tmp_pkt);

	// as long as there is still data in the package
	while(audio_pkg_size > 0)
	{
		// resize buffer if needed
		if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE)
		{
			buffer.resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, true);
			buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE;
		}

		// read samples from the packet
		data_size = buf_size - buf_pos;

		tmp_pkt.data = audio_pkg_data;
		tmp_pkt.size = audio_pkg_size;

		read_length = avcodec_decode_audio3(
			m_codecCtx,
			(int16_t*)(((data_t*)buffer.getBuffer()) + buf_pos),
			&data_size, &tmp_pkt);

		// read error, next packet!
		if(read_length < 0)
			break;

		buf_pos += data_size;

		// move packet parameters
		audio_pkg_data += read_length;
		audio_pkg_size -= read_length;
	}

	return buf_pos;
}
コード例 #4
0
void AUD_SoftwareDevice::mix(data_t* buffer, int length)
{
	lock();

	{
		AUD_SoftwareHandle* sound;
		int len;
		int pos;
		sample_t* buf;
		std::list<AUD_SoftwareHandle*> stopSounds;
		std::list<AUD_Buffer*> tempBufs;
		AUD_Buffer* tempbuf;
		int samplesize = AUD_SAMPLE_SIZE(m_specs);

		// for all sounds
		AUD_HandleIterator it = m_playingSounds.begin();
		while(it != m_playingSounds.end())
		{
			sound = *it;
			// increment the iterator to make sure it's valid,
			// in case the sound gets deleted after stopping
			++it;

			// get the buffer from the source
			pos = 0;
			len = length;
			sound->reader->read(len, buf);

			// in case of looping
			while(pos + len < length && sound->loopcount)
			{
				tempbuf = new AUD_Buffer(len * samplesize);
				memcpy(tempbuf->getBuffer(), buf, len * samplesize);
				tempBufs.push_back(tempbuf);
				m_mixer->add(tempbuf->getBuffer(), pos, len, sound->volume);

				pos += len;

				if(sound->loopcount > 0)
					sound->loopcount--;

				sound->reader->seek(0);

				len = length - pos;
				sound->reader->read(len, buf);

				// prevent endless loop
				if(!len)
					break;
			}

			m_mixer->add(buf, pos, len, sound->volume);
			pos += len;

			// in case the end of the sound is reached
			if(pos < length)
			{
				if(sound->stop)
					sound->stop(sound->stop_data);

				if(sound->keep)
					pause(sound);
				else
					stopSounds.push_back(sound);
			}
		}

		// superpose
		m_mixer->superpose(buffer, length, m_volume);

		// cleanup
		while(!stopSounds.empty())
		{
			sound = stopSounds.front();
			stopSounds.pop_front();
			stop(sound);
		}

		while(!tempBufs.empty())
		{
			tempbuf = tempBufs.front();
			tempBufs.pop_front();
			delete tempbuf;
		}
	}

	unlock();
}
コード例 #5
0
int AUD_FFMPEGReader::decode(AVPacket& packet, AUD_Buffer& buffer)
{
#ifdef FFMPEG_HAVE_DECODE_AUDIO4
	AVFrame* frame = NULL;
	int got_frame;
	int read_length;
	uint8_t* orig_data = packet.data;
	int orig_size = packet.size;

	int buf_size = buffer.getSize();
	int buf_pos = 0;

	while(packet.size > 0)
	{
		got_frame = 0;

		if(!frame)
			frame = avcodec_alloc_frame();
		else
			avcodec_get_frame_defaults(frame);

		read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
		if(read_length < 0)
			break;

		if(got_frame)
		{
			int data_size = av_samples_get_buffer_size(NULL, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1);

			if(buf_size - buf_pos < data_size)
			{
				buffer.resize(buf_size + data_size, true);
				buf_size += data_size;
			}

			if(m_tointerleave)
			{
				int single_size = data_size / m_codecCtx->channels / frame->nb_samples;
				for(int channel = 0; channel < m_codecCtx->channels; channel++)
				{
					for(int i = 0; i < frame->nb_samples; i++)
					{
						memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
							   frame->data[channel] + i * single_size, single_size);
					}
				}
			}
			else
				memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[0], data_size);

			buf_pos += data_size;
		}
		packet.size -= read_length;
		packet.data += read_length;
	}

	packet.data = orig_data;
	packet.size = orig_size;
	av_free(frame);

	return buf_pos;
#else
	// save packet parameters
	uint8_t *audio_pkg_data = packet.data;
	int audio_pkg_size = packet.size;

	int buf_size = buffer.getSize();
	int buf_pos = 0;

	int read_length, data_size;

	AVPacket tmp_pkt;

	av_init_packet(&tmp_pkt);

	// as long as there is still data in the package
	while(audio_pkg_size > 0)
	{
		// resize buffer if needed
		if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE)
		{
			buffer.resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, true);
			buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE;
		}

		// read samples from the packet
		data_size = buf_size - buf_pos;

		tmp_pkt.data = audio_pkg_data;
		tmp_pkt.size = audio_pkg_size;

		read_length = avcodec_decode_audio3(
			m_codecCtx,
			(int16_t*)(((data_t*)buffer.getBuffer()) + buf_pos),
			&data_size, &tmp_pkt);

		// read error, next packet!
		if(read_length < 0)
			break;

		buf_pos += data_size;

		// move packet parameters
		audio_pkg_data += read_length;
		audio_pkg_size -= read_length;
	}

	return buf_pos;
#endif
}