00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00026
00028 #include <SFML/Audio/SoundFileOgg.hpp>
00029 #include <iostream>
00030
00031
00032 namespace sf_private
00033 {
00037 sfSoundFileOgg::sfSoundFileOgg() :
00038 myFile(NULL)
00039 {
00040
00041 }
00042
00043
00047 sfSoundFileOgg::~sfSoundFileOgg()
00048 {
00049 if (myFile)
00050 {
00051 ov_clear(&myStream);
00052 myFile = NULL;
00053 }
00054 }
00055
00056
00060 bool sfSoundFileOgg::OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate)
00061 {
00062
00063 if (myFile)
00064 {
00065 ov_clear(&myStream);
00066 myFile = NULL;
00067 }
00068
00069
00070 myFile = fopen(Filename.c_str(), "rb");
00071 if (!myFile)
00072 {
00073 std::cerr << "Failed to read sound file \"" << Filename << "\" (cannot open the file)" << std::endl;
00074 return false;
00075 }
00076
00077
00078 int Error = ov_open(myFile, &myStream, NULL, 0);
00079 if (Error < 0)
00080 {
00081 std::cerr << "Failed to read sound file \"" << Filename << "\" (not a valid ogg-vorbis file)" << std::endl;
00082 fclose(myFile);
00083 myFile = NULL;
00084 return false;
00085 }
00086
00087
00088 vorbis_info* Infos = ov_info(&myStream, -1);
00089 ChannelsCount = Infos->channels;
00090 SampleRate = Infos->rate;
00091 NbSamples = static_cast<std::size_t>(ov_pcm_total(&myStream, -1) * ChannelsCount);
00092
00093
00094
00095
00096
00097
00098
00099
00100 return true;
00101 }
00102
00103
00107 std::size_t sfSoundFileOgg::Read(sfInt16* Data, std::size_t NbSamples)
00108 {
00109
00110
00111 long TotalSize = static_cast<long>(NbSamples * sizeof(sfInt16));
00112 long TotalRead = 0;
00113 while (TotalRead < TotalSize)
00114 {
00115
00116 char* Ptr = reinterpret_cast<char*>(Data) + TotalRead;
00117 int Len = TotalSize - TotalRead;
00118 long Read = ov_read(&myStream, Ptr, Len, 0, 2, 1, NULL);
00119
00120 if (Read > 0)
00121 {
00122
00123 TotalRead += Read;
00124 }
00125 else if (Read == 0)
00126 {
00127
00128 break;
00129 }
00130 else
00131 {
00132
00133 std::cerr << "Failed to read from ogg file" << std::endl;
00134 break;
00135 }
00136 }
00137
00138 return static_cast<std::size_t>(TotalRead / sizeof(sfInt16));
00139 }
00140
00141 }