Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/psx/mednadisc/cdrom/CDAFReader_SF.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_SF.h"
21
22
#include <sndfile.h>
23
24
class CDAFReader_SF final : public CDAFReader
25
{
26
public:
27
28
CDAFReader_SF(Stream *fp);
29
~CDAFReader_SF();
30
31
uint64 Read_(int16 *buffer, uint64 frames) override;
32
bool Seek_(uint64 frame_offset) override;
33
uint64 FrameCount(void) override;
34
35
private:
36
SNDFILE *sf;
37
SF_INFO sfinfo;
38
SF_VIRTUAL_IO sfvf;
39
40
Stream *fw;
41
};
42
43
static sf_count_t isf_get_filelen(void *user_data)
44
{
45
Stream *fw = (Stream*)user_data;
46
47
try
48
{
49
return fw->size();
50
}
51
catch(...)
52
{
53
return(-1);
54
}
55
}
56
57
static sf_count_t isf_seek(sf_count_t offset, int whence, void *user_data)
58
{
59
Stream *fw = (Stream*)user_data;
60
61
try
62
{
63
//printf("Seek: offset=%lld, whence=%lld\n", (long long)offset, (long long)whence);
64
65
fw->seek(offset, whence);
66
return fw->tell();
67
}
68
catch(...)
69
{
70
//printf(" SEEK FAILED\n");
71
return(-1);
72
}
73
}
74
75
static sf_count_t isf_read(void *ptr, sf_count_t count, void *user_data)
76
{
77
Stream *fw = (Stream*)user_data;
78
79
try
80
{
81
sf_count_t ret = fw->read(ptr, count, false);
82
83
//printf("Read: count=%lld, ret=%lld\n", (long long)count, (long long)ret);
84
85
return ret;
86
}
87
catch(...)
88
{
89
//printf(" READ FAILED\n");
90
return(0);
91
}
92
}
93
94
static sf_count_t isf_write(const void *ptr, sf_count_t count, void *user_data)
95
{
96
return(0);
97
}
98
99
static sf_count_t isf_tell(void *user_data)
100
{
101
Stream *fw = (Stream*)user_data;
102
103
try
104
{
105
return fw->tell();
106
}
107
catch(...)
108
{
109
return(-1);
110
}
111
}
112
113
CDAFReader_SF::CDAFReader_SF(Stream *fp) : fw(fp)
114
{
115
memset(&sfvf, 0, sizeof(sfvf));
116
sfvf.get_filelen = isf_get_filelen;
117
sfvf.seek = isf_seek;
118
sfvf.read = isf_read;
119
sfvf.write = isf_write;
120
sfvf.tell = isf_tell;
121
122
memset(&sfinfo, 0, sizeof(sfinfo));
123
if(!(sf = sf_open_virtual(&sfvf, SFM_READ, &sfinfo, (void*)fp)))
124
throw(0);
125
}
126
127
CDAFReader_SF::~CDAFReader_SF()
128
{
129
sf_close(sf);
130
}
131
132
uint64 CDAFReader_SF::Read_(int16 *buffer, uint64 frames)
133
{
134
return(sf_read_short(sf, (short*)buffer, frames * 2) / 2);
135
}
136
137
bool CDAFReader_SF::Seek_(uint64 frame_offset)
138
{
139
// FIXME error condition
140
if((uint64)sf_seek(sf, frame_offset, SEEK_SET) != frame_offset)
141
return(false);
142
143
return(true);
144
}
145
146
uint64 CDAFReader_SF::FrameCount(void)
147
{
148
return(sfinfo.frames);
149
}
150
151
152
CDAFReader* CDAFR_SF_Open(Stream* fp)
153
{
154
return new CDAFReader_SF(fp);
155
}
156
157