summaryrefslogtreecommitdiff
path: root/drivers/theoraplayer/src/TheoraAudioPacketQueue.cpp
blob: be5e1018f9ed7422f9493ca0599c30c5581d7d50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/************************************************************************************
This source file is part of the Theora Video Playback Library
For latest info, see http://libtheoraplayer.googlecode.com
*************************************************************************************
Copyright (c) 2008-2014 Kresimir Spes (kspes@cateia.com)
This program is free software; you can redistribute it and/or modify it under
the terms of the BSD license: http://opensource.org/licenses/BSD-3-Clause
*************************************************************************************/
#include <stdlib.h>
#include "TheoraAudioPacketQueue.h"
#include "TheoraAudioInterface.h"

TheoraAudioPacketQueue::TheoraAudioPacketQueue()
{
	mTheoraAudioPacketQueue = NULL;
}

TheoraAudioPacketQueue::~TheoraAudioPacketQueue()
{
	destroyAllAudioPackets();
}

float TheoraAudioPacketQueue::getAudioPacketQueueLength()
{
	float len = 0;
	for (TheoraAudioPacket* p = mTheoraAudioPacketQueue; p != NULL; p = p->next)
		len += p->numSamples;
	
	return len / (mAudioFrequency * mNumAudioChannels);
}

void TheoraAudioPacketQueue::_addAudioPacket(float* data, int numSamples)
{
	TheoraAudioPacket* packet = new TheoraAudioPacket;
	packet->pcm = data;
	packet->numSamples = numSamples;
	packet->next = NULL;


	if (mTheoraAudioPacketQueue == NULL) mTheoraAudioPacketQueue = packet;
	else
	{
		TheoraAudioPacket* last = mTheoraAudioPacketQueue;
		for (TheoraAudioPacket* p = last; p != NULL; p = p->next)
			last = p;
		last->next = packet;
	}
}

void TheoraAudioPacketQueue::addAudioPacket(float** buffer, int numSamples, float gain)
{
	float* data = new float[numSamples * mNumAudioChannels];
	float* dataptr = data;
	int i;
	unsigned int j;
	
	if (gain < 1.0f)
	{
		// apply gain, let's attenuate the samples
		for (i = 0; i < numSamples; ++i)
			for (j = 0; j < mNumAudioChannels; j++, ++dataptr)
				*dataptr = buffer[i][j] * gain;
	}
	else
	{
		// do a simple copy, faster then the above method, when gain is 1.0f
		for (i = 0; i < numSamples; ++i)
			for (j = 0; j < mNumAudioChannels; j++, ++dataptr)
				*dataptr = buffer[j][i];
	}
		
	_addAudioPacket(data, numSamples * mNumAudioChannels);
}

void TheoraAudioPacketQueue::addAudioPacket(float* buffer, int numSamples, float gain)
{
	float* data = new float[numSamples * mNumAudioChannels];
	float* dataptr = data;
	int i, numFloats = numSamples * mNumAudioChannels;
	
	if (gain < 1.0f)
	{
		// apply gain, let's attenuate the samples
		for (i = 0; i < numFloats; ++i, dataptr++)
			*dataptr = buffer[i] * gain;
	}
	else
	{
		// do a simple copy, faster then the above method, when gain is 1.0f
		for (i = 0; i < numFloats; ++i, dataptr++)
			*dataptr = buffer[i];
	}
	
	_addAudioPacket(data, numFloats);
}

TheoraAudioPacket* TheoraAudioPacketQueue::popAudioPacket()
{
	if (mTheoraAudioPacketQueue == NULL) return NULL;
	TheoraAudioPacket* p = mTheoraAudioPacketQueue;
	mTheoraAudioPacketQueue = mTheoraAudioPacketQueue->next;
	return p;
}

void TheoraAudioPacketQueue::destroyAudioPacket(TheoraAudioPacket* p)
{
	if (p == NULL) return;
	delete [] p->pcm;
	delete p;
}

void TheoraAudioPacketQueue::destroyAllAudioPackets()
{
	for (TheoraAudioPacket* p = popAudioPacket(); p != NULL; p = popAudioPacket())
		destroyAudioPacket(p);
}

void TheoraAudioPacketQueue::flushAudioPackets(TheoraAudioInterface* audioInterface)
{
	
	for (TheoraAudioPacket* p = popAudioPacket(); p != NULL; p = popAudioPacket())
	{
		audioInterface->insertData(p->pcm, p->numSamples);
		destroyAudioPacket(p);
	}
}