~x3lectric/xbmc/svn-trunk

10178 by vulkanr
merge with trunk. revision 13100.
1
/*
2
 *      Copyright (C) 2005-2008 Team XBMC
3
 *      http://www.xbmc.org
4
 *
5
 *  This Program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2, or (at your option)
8
 *  any later version.
9
 *
10
 *  This Program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with XBMC; see the file COPYING.  If not, write to
17
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18
 *  http://www.gnu.org/copyleft/gpl.html
19
 *
20
 */
21
17258 by spiff_
changed: bye bye include.h
22
#include "system.h"
6019 by bobbin007
changed: cleanup of guiaudiomanager
23
#include "GUISound.h"
8025 by yuvalt
Convert graphics library to SDL
24
#include "AudioContext.h"
10043 by vulkanr
merge with trunk. rev. 12805.
25
#include "Settings.h"
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
26
#include "FileSystem/File.h"
17274 by jmarshallnz
fixed: Win32 build after include.h removal.
27
#include "utils/log.h"
8432 by jmarshallnz
fixed: Various issues to allow compilation on win32.
28
#ifdef HAS_SDL_AUDIO
8053 by yuvalt
Add GUI sound
29
#include <SDL/SDL_mixer.h>
13687 by jmarshallnz
fixed: Nav sounds on linux + OS X.
30
#include "FileSystem/SpecialProtocol.h"
8053 by yuvalt
Add GUI sound
31
#endif
8432 by jmarshallnz
fixed: Various issues to allow compilation on win32.
32
#ifndef HAS_SDL_AUDIO
8523 by jmarshallnz
merged: Revisions 9635 -> 9702 changes from trunk.
33
6019 by bobbin007
changed: cleanup of guiaudiomanager
34
typedef struct
35
{
36
  char chunk_id[4];
37
  long chunksize;
38
} WAVE_CHUNK;
39
40
typedef struct
41
{
42
  char riff[4];
43
  long filesize;
44
  char rifftype[4];
45
} WAVE_RIFFHEADER;
8053 by yuvalt
Add GUI sound
46
#else
14108 by spiff_
cosmetics
47
#define GUI_SOUND_CHANNEL 0
8053 by yuvalt
Add GUI sound
48
#endif
6019 by bobbin007
changed: cleanup of guiaudiomanager
49
50
CGUISound::CGUISound()
51
{
52
  m_soundBuffer=NULL;
53
}
54
55
CGUISound::~CGUISound()
56
{
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
57
#ifdef _WIN32
9174 by monkeyman_67156
update: More trunk synchronization. Sorry, no dvdplayer.
58
  FreeBuffer();
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
59
#elif defined(HAS_SDL_AUDIO)
10381 by spiff_
fixed: memory leak in gui sounds - cheers riquedafreak
60
  Mix_FreeChunk(m_soundBuffer);
8025 by yuvalt
Convert graphics library to SDL
61
#endif
6019 by bobbin007
changed: cleanup of guiaudiomanager
62
}
63
64
// \brief Loads a wav file by filename
65
bool CGUISound::Load(const CStdString& strFile)
66
{
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
67
#ifdef _WIN32
6019 by bobbin007
changed: cleanup of guiaudiomanager
68
  LPBYTE pbData=NULL;
69
  WAVEFORMATEX wfx;
70
  int size=0;
71
  if (!LoadWav(strFile, &wfx, &pbData, &size))
72
    return false;
73
74
  bool bReady=(CreateBuffer(&wfx, size) && FillBuffer(pbData, size));
75
76
  if (!bReady)
77
    FreeBuffer();
78
79
  delete[] pbData;
80
81
  return bReady;
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
82
#elif defined(HAS_SDL_AUDIO)
13687 by jmarshallnz
fixed: Nav sounds on linux + OS X.
83
  m_soundBuffer = Mix_LoadWAV(_P(strFile));
8053 by yuvalt
Add GUI sound
84
  if (!m_soundBuffer)
85
    return false;
14108 by spiff_
cosmetics
86
87
  return true;
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
88
#else
89
  return false;
8025 by yuvalt
Convert graphics library to SDL
90
#endif
6019 by bobbin007
changed: cleanup of guiaudiomanager
91
}
92
93
// \brief Starts playback of the sound
94
void CGUISound::Play()
95
{
96
  if (m_soundBuffer)
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
97
  {
98
#ifdef _WIN32
6765 by jmarshallnz
added: Initial skin version 2.1 changes and support for building for win32.
99
    m_soundBuffer->Play(0, 0, 0);
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
100
#elif defined(HAS_SDL_AUDIO)
14108 by spiff_
cosmetics
101
    Mix_PlayChannel(GUI_SOUND_CHANNEL, m_soundBuffer, 0);
8025 by yuvalt
Convert graphics library to SDL
102
#endif
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
103
  }
6019 by bobbin007
changed: cleanup of guiaudiomanager
104
}
105
106
// \brief returns true if the sound is playing
107
bool CGUISound::IsPlaying()
108
{
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
109
#ifdef _WIN32
6019 by bobbin007
changed: cleanup of guiaudiomanager
110
  if (m_soundBuffer)
111
  {
112
    DWORD dwStatus;
113
    m_soundBuffer->GetStatus(&dwStatus);
114
    return (dwStatus & DSBSTATUS_PLAYING);
115
  }
116
117
  return false;
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
118
#elif defined(HAS_SDL_AUDIO)
8207 by jmarshallnz
fixed: Various compilation issues/warnings under win32
119
  return Mix_Playing(GUI_SOUND_CHANNEL) != 0;
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
120
#else
121
  return false;
8025 by yuvalt
Convert graphics library to SDL
122
#endif
6019 by bobbin007
changed: cleanup of guiaudiomanager
123
}
124
125
// \brief Stops playback if the sound
126
void CGUISound::Stop()
127
{
128
  if (m_soundBuffer)
129
  {
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
130
#ifdef _WIN32
6765 by jmarshallnz
added: Initial skin version 2.1 changes and support for building for win32.
131
    m_soundBuffer->Stop();
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
132
#elif defined(HAS_SDL_AUDIO)
14108 by spiff_
cosmetics
133
    Mix_HaltChannel(GUI_SOUND_CHANNEL);
6765 by jmarshallnz
added: Initial skin version 2.1 changes and support for building for win32.
134
#endif
6019 by bobbin007
changed: cleanup of guiaudiomanager
135
10342 by monkeyman_67156
fixed: various warnings produced by -Wextra, and -pedantic on gcc 4.3+
136
    while(IsPlaying()) {}
6019 by bobbin007
changed: cleanup of guiaudiomanager
137
  }
138
}
139
140
// \brief Sets the volume of the sound
141
void CGUISound::SetVolume(int level)
142
{
143
  if (m_soundBuffer)
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
144
  {
145
#ifdef _WIN32
6019 by bobbin007
changed: cleanup of guiaudiomanager
146
    m_soundBuffer->SetVolume(level);
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
147
#elif defined(HAS_SDL_AUDIO)
8053 by yuvalt
Add GUI sound
148
    Mix_Volume(GUI_SOUND_CHANNEL, level);
14108 by spiff_
cosmetics
149
#endif
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
150
  }
6019 by bobbin007
changed: cleanup of guiaudiomanager
151
}
152
17007 by yuvalt
GUISound now compiles even without SDL_AUDIO nor Win32
153
#ifdef _WIN32
6019 by bobbin007
changed: cleanup of guiaudiomanager
154
bool CGUISound::CreateBuffer(LPWAVEFORMATEX wfx, int iLength)
155
{
156
  //  Set up DSBUFFERDESC structure
14108 by spiff_
cosmetics
157
  DSBUFFERDESC dsbdesc;
158
  memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
6765 by jmarshallnz
added: Initial skin version 2.1 changes and support for building for win32.
159
  dsbdesc.dwSize=sizeof(DSBUFFERDESC);
160
  // directsound requires ctrlvolume to be set
161
  dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME;
14108 by spiff_
cosmetics
162
  dsbdesc.dwBufferBytes=iLength;
6019 by bobbin007
changed: cleanup of guiaudiomanager
163
  dsbdesc.lpwfxFormat=wfx;
164
165
  LPDIRECTSOUND directSound=g_audioContext.GetDirectSoundDevice();
166
  if (!directSound)
167
    return false;
168
169
  //  Create buffer
170
  if (FAILED(directSound->CreateSoundBuffer(&dsbdesc, &m_soundBuffer, NULL)))
171
  {
172
    m_soundBuffer = NULL;
173
    CLog::Log(LOGERROR, __FUNCTION__" Creating sound buffer failed!");
174
    return false;
175
  }
176
177
  //  Make effects as loud as possible
19482 by spiff_
changed: get rid of the useless stSettings struct
178
  m_soundBuffer->SetVolume(g_settings.m_nVolumeLevel);
6019 by bobbin007
changed: cleanup of guiaudiomanager
179
14108 by spiff_
cosmetics
180
  return true;
6019 by bobbin007
changed: cleanup of guiaudiomanager
181
}
182
183
bool CGUISound::FillBuffer(LPBYTE pbData, int iLength)
184
{
185
  if (!m_soundBuffer)
186
    return false;
187
188
  LPVOID lpvWrite;
189
  DWORD  dwLength;
190
191
  if (SUCCEEDED(m_soundBuffer->Lock(0, 0, &lpvWrite, &dwLength, NULL, NULL, DSBLOCK_ENTIREBUFFER)))
192
  {
6497 by elupus
changed: switch to standard memcpy/set since fast_memcpy/set is generally alot slower than standard xdk versions.
193
    memcpy(lpvWrite, pbData, iLength);
6019 by bobbin007
changed: cleanup of guiaudiomanager
194
    m_soundBuffer->Unlock(lpvWrite, dwLength, NULL, 0);
195
    return true;
196
  }
197
198
  CLog::Log(LOGERROR, __FUNCTION__" Filling sound buffer failed!");
199
200
  return false;
201
}
202
203
void CGUISound::FreeBuffer()
204
{
205
  if (IsPlaying())
206
    Stop();
207
208
  SAFE_RELEASE(m_soundBuffer);
209
}
210
211
bool CGUISound::LoadWav(const CStdString& strFile, WAVEFORMATEX* wfx, LPBYTE* ppWavData, int* pDataSize)
212
{
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
213
  XFILE::CFile file;
214
  if (!file.Open(strFile))
6019 by bobbin007
changed: cleanup of guiaudiomanager
215
    return false;
216
217
  // read header
218
  WAVE_RIFFHEADER riffh;
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
219
  file.Read(&riffh, sizeof(WAVE_RIFFHEADER));
6019 by bobbin007
changed: cleanup of guiaudiomanager
220
221
  // file valid?
222
  if (strncmp(riffh.riff, "RIFF", 4)!=0 && strncmp(riffh.rifftype, "WAVE", 4)!=0)
223
  {
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
224
    file.Close();
6019 by bobbin007
changed: cleanup of guiaudiomanager
225
    return false;
226
  }
227
228
  long offset=0;
229
  offset += sizeof(WAVE_RIFFHEADER);
230
  offset -= sizeof(WAVE_CHUNK);
231
232
  // parse chunks
233
  do
234
  {
235
    WAVE_CHUNK chunk;
236
237
    // always seeking to the start of a chunk
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
238
    file.Seek(offset + sizeof(WAVE_CHUNK), SEEK_SET);
239
    file.Read(&chunk, sizeof(WAVE_CHUNK));
6019 by bobbin007
changed: cleanup of guiaudiomanager
240
241
    if (!strncmp(chunk.chunk_id, "fmt ", 4))
242
    { // format chunk
243
      memset(wfx, 0, sizeof(WAVEFORMATEX));
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
244
      file.Read(wfx, 16);
6019 by bobbin007
changed: cleanup of guiaudiomanager
245
      // we only need 16 bytes of the fmt chunk
246
      if (chunk.chunksize-16>0)
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
247
        file.Seek(chunk.chunksize-16, SEEK_CUR);
6019 by bobbin007
changed: cleanup of guiaudiomanager
248
    }
249
    else if (!strncmp(chunk.chunk_id, "data", 4))
250
    { // data chunk
251
      *ppWavData=new BYTE[chunk.chunksize+1];
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
252
      file.Read(*ppWavData, chunk.chunksize);
6019 by bobbin007
changed: cleanup of guiaudiomanager
253
      *pDataSize=chunk.chunksize;
254
255
      if (chunk.chunksize & 1)
256
        offset++;
257
    }
258
    else
259
    { // other chunk - unused, just skip
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
260
      file.Seek(chunk.chunksize, SEEK_CUR);
6019 by bobbin007
changed: cleanup of guiaudiomanager
261
    }
262
263
    offset+=(chunk.chunksize+sizeof(WAVE_CHUNK));
264
265
    if (offset & 1)
266
      offset++;
267
268
  } while (offset+(int)sizeof(WAVE_CHUNK) < riffh.filesize);
269
12289 by jmarshallnz
fixed: More utf8 fixes for win32 (addresses ticket #5065)
270
  file.Close();
6019 by bobbin007
changed: cleanup of guiaudiomanager
271
  return (*ppWavData!=NULL);
272
}
9173 by d4rkm4ster
merge: with trunk rev 11396 (except dvdplayer)
273
8025 by yuvalt
Convert graphics library to SDL
274
#endif