Line data Source code
1 : /* Copyright (C) 2015 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "precompiled.h"
19 :
20 : #include "OggData.h"
21 :
22 : #if CONFIG2_AUDIO
23 :
24 : #include "ps/CLogger.h"
25 : #include "ps/CLogger.h"
26 : #include "ps/Filesystem.h"
27 : #include "soundmanager/SoundManager.h"
28 :
29 0 : COggData::COggData()
30 0 : : m_Format(0), m_Frequency(0), m_OneShot(false), m_BuffersUsed(0)
31 : {
32 0 : }
33 :
34 0 : COggData::~COggData()
35 : {
36 0 : AL_CHECK;
37 0 : if (ogg)
38 0 : ogg->Close();
39 :
40 0 : AL_CHECK;
41 0 : if ( m_BuffersUsed > 0 )
42 0 : alDeleteBuffers(m_BuffersUsed, &m_Buffer[0]);
43 :
44 0 : AL_CHECK;
45 0 : m_BuffersUsed = 0;
46 0 : }
47 :
48 0 : void COggData::SetFormatAndFreq(int form, ALsizei freq)
49 : {
50 0 : m_Format = form;
51 0 : m_Frequency = freq;
52 0 : }
53 :
54 0 : bool COggData::IsStereo()
55 : {
56 0 : return m_Format == AL_FORMAT_STEREO16;
57 : }
58 :
59 0 : bool COggData::InitOggFile(const VfsPath& itemPath)
60 : {
61 0 : CSoundManager* sndManager = (CSoundManager*)g_SoundManager;
62 0 : if (!sndManager)
63 0 : return false;
64 :
65 0 : int buffersToStart = sndManager->GetBufferCount();
66 0 : if (OpenOggNonstream(g_VFS, itemPath, ogg) != INFO::OK)
67 0 : return false;
68 :
69 0 : m_FileFinished = false;
70 :
71 0 : SetFormatAndFreq(ogg->Format(), ogg->SamplingRate());
72 0 : SetFileName(itemPath);
73 :
74 0 : AL_CHECK;
75 :
76 0 : alGenBuffers(buffersToStart, m_Buffer);
77 :
78 0 : ALenum err = alGetError();
79 0 : if (err != AL_NO_ERROR)
80 : {
81 0 : LOGERROR("Failed to create initial buffer. OpenAL error: %s\n", alGetString(err));
82 0 : return false;
83 : }
84 :
85 0 : m_BuffersUsed = FetchDataIntoBuffer(buffersToStart, m_Buffer);
86 0 : if (m_FileFinished)
87 : {
88 0 : m_OneShot = true;
89 0 : if (m_BuffersUsed < buffersToStart)
90 : {
91 0 : alDeleteBuffers(buffersToStart - m_BuffersUsed, &m_Buffer[m_BuffersUsed]);
92 : }
93 : }
94 0 : AL_CHECK;
95 :
96 0 : return true;
97 : }
98 :
99 0 : ALsizei COggData::GetBufferCount()
100 : {
101 0 : return m_BuffersUsed;
102 : }
103 :
104 0 : bool COggData::IsFileFinished()
105 : {
106 0 : return m_FileFinished;
107 : }
108 :
109 0 : void COggData::ResetFile()
110 : {
111 0 : ogg->ResetFile();
112 0 : m_FileFinished = false;
113 0 : }
114 :
115 0 : bool COggData::IsOneShot()
116 : {
117 0 : return m_OneShot;
118 : }
119 :
120 0 : int COggData::FetchDataIntoBuffer(int count, ALuint* buffers)
121 : {
122 0 : CSoundManager* sndManager = (CSoundManager*)g_SoundManager;
123 0 : if (!sndManager)
124 0 : return 0;
125 :
126 0 : long bufferSize = sndManager->GetBufferSize();
127 :
128 0 : u8* pcmout = new u8[bufferSize + 5000];
129 0 : int buffersWritten = 0;
130 :
131 0 : for (int i = 0; i < count && !m_FileFinished; ++i)
132 : {
133 0 : memset(pcmout, 0, bufferSize + 5000);
134 0 : Status totalRet = ogg->GetNextChunk(pcmout, bufferSize);
135 0 : m_FileFinished = ogg->atFileEOF();
136 0 : if (totalRet > 0)
137 : {
138 0 : buffersWritten++;
139 0 : alBufferData(buffers[i], m_Format, pcmout, (ALsizei)totalRet, (int)m_Frequency);
140 : }
141 : }
142 0 : delete[] pcmout;
143 0 : return buffersWritten;
144 : }
145 :
146 :
147 0 : ALuint COggData::GetBuffer()
148 : {
149 0 : return m_Buffer[0];
150 : }
151 :
152 0 : ALuint* COggData::GetBufferPtr()
153 : {
154 0 : return m_Buffer;
155 3 : }
156 :
157 : #endif // CONFIG2_AUDIO
|