SoundFileOgg.cpp
1 //
3 // SFML - Simple and Fast Multimedia Library
4 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
5 //
6 // This software is provided 'as-is', without any express or implied warranty.
7 // In no event will the authors be held liable for any damages arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it freely,
11 // subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented;
14 // you must not claim that you wrote the original software.
15 // If you use this software in a product, an acknowledgment
16 // in the product documentation would be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such,
19 // and must not be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source distribution.
22 //
24 
26 // Headers
28 #include <SFML/Audio/SoundFileOgg.hpp>
29 #include <SFML/Audio/stb_vorbis/stb_vorbis.h>
30 #include <iostream>
31 
32 
33 namespace sf
34 {
35 namespace priv
36 {
40 SoundFileOgg::SoundFileOgg() :
41 myStream (NULL),
42 myChannelsCount(0)
43 {
44 
45 }
46 
47 
51 SoundFileOgg::~SoundFileOgg()
52 {
53  if (myStream)
54  stb_vorbis_close(myStream);
55 }
56 
57 
61 bool SoundFileOgg::IsFileSupported(const std::string& Filename, bool Read)
62 {
63  if (Read)
64  {
65  // Open the vorbis stream
66  stb_vorbis* Stream = stb_vorbis_open_filename(const_cast<char*>(Filename.c_str()), NULL, NULL);
67 
68  if (Stream)
69  {
70  stb_vorbis_close(Stream);
71  return true;
72  }
73  else
74  {
75  return false;
76  }
77  }
78  else
79  {
80  // No support for writing ogg files yet...
81  return false;
82  }
83 }
84 
85 
89 bool SoundFileOgg::IsFileSupported(const char* Data, std::size_t SizeInBytes)
90 {
91  // Open the vorbis stream
92  unsigned char* Buffer = reinterpret_cast<unsigned char*>(const_cast<char*>(Data));
93  int Length = static_cast<int>(SizeInBytes);
94  stb_vorbis* Stream = stb_vorbis_open_memory(Buffer, Length, NULL, NULL);
95 
96  if (Stream)
97  {
98  stb_vorbis_close(Stream);
99  return true;
100  }
101  else
102  {
103  return false;
104  }
105 }
106 
107 
111 bool SoundFileOgg::OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate)
112 {
113  // Close the file if already opened
114  if (myStream)
115  stb_vorbis_close(myStream);
116 
117  // Open the vorbis stream
118  myStream = stb_vorbis_open_filename(const_cast<char*>(Filename.c_str()), NULL, NULL);
119  if (myStream == NULL)
120  {
121  std::cerr << "Failed to read sound file \"" << Filename << "\" (cannot open the file)" << std::endl;
122  return false;
123  }
124 
125  // Get the music parameters
126  stb_vorbis_info Infos = stb_vorbis_get_info(myStream);
127  ChannelsCount = myChannelsCount = Infos.channels;
128  SampleRate = Infos.sample_rate;
129  NbSamples = static_cast<std::size_t>(stb_vorbis_stream_length_in_samples(myStream) * ChannelsCount);
130 
131  return true;
132 }
133 
134 
138 bool SoundFileOgg::OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate)
139 {
140  // Close the file if already opened
141  if (myStream)
142  stb_vorbis_close(myStream);
143 
144  // Open the vorbis stream
145  unsigned char* Buffer = reinterpret_cast<unsigned char*>(const_cast<char*>(Data));
146  int Length = static_cast<int>(SizeInBytes);
147  myStream = stb_vorbis_open_memory(Buffer, Length, NULL, NULL);
148  if (myStream == NULL)
149  {
150  std::cerr << "Failed to read sound file from memory (cannot open the file)" << std::endl;
151  return false;
152  }
153 
154  // Get the music parameters
155  stb_vorbis_info Infos = stb_vorbis_get_info(myStream);
156  ChannelsCount = myChannelsCount = Infos.channels;
157  SampleRate = Infos.sample_rate;
158  NbSamples = static_cast<std::size_t>(stb_vorbis_stream_length_in_samples(myStream) * ChannelsCount);
159 
160  return true;
161 }
162 
163 
167 std::size_t SoundFileOgg::Read(Int16* Data, std::size_t NbSamples)
168 {
169  if (myStream && Data && NbSamples)
170  {
171  int Read = stb_vorbis_get_samples_short_interleaved(myStream, myChannelsCount, Data, static_cast<int>(NbSamples));
172  return static_cast<std::size_t>(Read * myChannelsCount);
173  }
174  else
175  {
176  return 0;
177  }
178 }
179 
180 } // namespace priv
181 
182 } // namespace sf