Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/psx/mednadisc/cdrom/CDAFReader_Vorbis.cpp
2 views
1
/* Mednafen - Multi-system Emulator
2
*
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
7
*
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
12
*
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
*/
17
18
#include <mednafen/mednafen.h>
19
#include "CDAFReader.h"
20
#include "CDAFReader_Vorbis.h"
21
22
#if 0
23
#include <tremor/ivorbisfile.h>
24
#else
25
#include <mednafen/tremor/ivorbisfile.h>
26
#endif
27
28
class CDAFReader_Vorbis final : public CDAFReader
29
{
30
public:
31
CDAFReader_Vorbis(Stream *fp);
32
~CDAFReader_Vorbis();
33
34
uint64 Read_(int16 *buffer, uint64 frames) override;
35
bool Seek_(uint64 frame_offset) override;
36
uint64 FrameCount(void) override;
37
38
private:
39
OggVorbis_File ovfile;
40
Stream *fw;
41
};
42
43
44
static size_t iov_read_func(void *ptr, size_t size, size_t nmemb, void *user_data)
45
{
46
Stream *fw = (Stream*)user_data;
47
48
if(!size)
49
return(0);
50
51
try
52
{
53
return fw->read(ptr, size * nmemb, false) / size;
54
}
55
catch(...)
56
{
57
return(0);
58
}
59
}
60
61
static int iov_seek_func(void *user_data, ogg_int64_t offset, int whence)
62
{
63
Stream *fw = (Stream*)user_data;
64
65
try
66
{
67
fw->seek(offset, whence);
68
return(0);
69
}
70
catch(...)
71
{
72
return(-1);
73
}
74
}
75
76
static int iov_close_func(void *user_data)
77
{
78
Stream *fw = (Stream*)user_data;
79
80
try
81
{
82
fw->close();
83
return(0);
84
}
85
catch(...)
86
{
87
return EOF;
88
}
89
}
90
91
static long iov_tell_func(void *user_data)
92
{
93
Stream *fw = (Stream*)user_data;
94
95
try
96
{
97
return fw->tell();
98
}
99
catch(...)
100
{
101
return(-1);
102
}
103
}
104
105
CDAFReader_Vorbis::CDAFReader_Vorbis(Stream *fp) : fw(fp)
106
{
107
ov_callbacks cb;
108
109
memset(&cb, 0, sizeof(cb));
110
cb.read_func = iov_read_func;
111
cb.seek_func = iov_seek_func;
112
cb.close_func = iov_close_func;
113
cb.tell_func = iov_tell_func;
114
115
if(ov_open_callbacks(fp, &ovfile, NULL, 0, cb))
116
throw(0);
117
}
118
119
CDAFReader_Vorbis::~CDAFReader_Vorbis()
120
{
121
ov_clear(&ovfile);
122
}
123
124
uint64 CDAFReader_Vorbis::Read_(int16 *buffer, uint64 frames)
125
{
126
uint8 *tw_buf = (uint8 *)buffer;
127
int cursection = 0;
128
long toread = frames * sizeof(int16) * 2;
129
130
while(toread > 0)
131
{
132
long didread = ov_read(&ovfile, (char*)tw_buf, toread, &cursection);
133
134
if(didread == 0)
135
break;
136
137
tw_buf = (uint8 *)tw_buf + didread;
138
toread -= didread;
139
}
140
141
return(frames - toread / sizeof(int16) / 2);
142
}
143
144
bool CDAFReader_Vorbis::Seek_(uint64 frame_offset)
145
{
146
ov_pcm_seek(&ovfile, frame_offset);
147
return(true);
148
}
149
150
uint64 CDAFReader_Vorbis::FrameCount(void)
151
{
152
return(ov_pcm_total(&ovfile, -1));
153
}
154
155
CDAFReader* CDAFR_Vorbis_Open(Stream* fp)
156
{
157
return new CDAFReader_Vorbis(fp);
158
}
159
160