SoundFileOgg.cpp
1
2//
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
33namespace sf
34{
35namespace priv
36{
40SoundFileOgg::SoundFileOgg() :
41myStream (NULL),
42myChannelsCount(0)
43{
44
45}
46
47
51SoundFileOgg::~SoundFileOgg()
52{
53 if (myStream)
54 stb_vorbis_close(myStream);
55}
56
57
61bool 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
89bool 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
111bool 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
138bool 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
167std::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