12 static ssize_t
r_read(void *user_data
, void *ptr
, size_t count
)
14 std::istream
*file
= reinterpret_cast<std::istream
*>(user_data
);
17 file
->read(reinterpret_cast<char*>(ptr
), count
);
18 return file
->gcount();
21 static off_t
r_lseek(void *user_data
, off_t offset
, int whence
)
23 std::istream
*file
= reinterpret_cast<std::istream
*>(user_data
);
26 if(!file
->seekg(offset
, std::ios::seekdir(whence
)))
32 class Mpg123Decoder final
: public Decoder
{
33 UniquePtr
<std::istream
> mFile
;
35 mpg123_handle
*mMpg123
;
40 Mpg123Decoder(UniquePtr
<std::istream
> file
, mpg123_handle
*mpg123
, int chans
, long srate
)
41 : mFile(std::move(file
)), mMpg123(mpg123
), mChannels(chans
), mSampleRate(srate
)
43 ~Mpg123Decoder() override
;
45 ALuint
getFrequency() const override
;
46 ChannelConfig
getChannelConfig() const override
;
47 SampleType
getSampleType() const override
;
49 uint64_t getLength() const override
;
50 bool seek(uint64_t pos
) override
;
52 std::pair
<uint64_t,uint64_t> getLoopPoints() const override
;
54 ALuint
read(ALvoid
*ptr
, ALuint count
) override
;
57 Mpg123Decoder::~Mpg123Decoder()
59 mpg123_close(mMpg123
);
60 mpg123_delete(mMpg123
);
65 ALuint
Mpg123Decoder::getFrequency() const
70 ChannelConfig
Mpg123Decoder::getChannelConfig() const
73 return ChannelConfig::Mono
;
75 return ChannelConfig::Stereo
;
76 throw std::runtime_error("Unsupported sample configuration");
79 SampleType
Mpg123Decoder::getSampleType() const
81 return SampleType::Int16
;
85 uint64_t Mpg123Decoder::getLength() const
87 off_t len
= mpg123_length(mMpg123
);
88 return (ALuint
)std::max
<off_t
>(len
, 0);
91 bool Mpg123Decoder::seek(uint64_t pos
)
93 off_t newpos
= mpg123_seek(mMpg123
, pos
, SEEK_SET
);
94 if(newpos
< 0) return false;
98 std::pair
<uint64_t,uint64_t> Mpg123Decoder::getLoopPoints() const
100 return std::make_pair(0, 0);
103 ALuint
Mpg123Decoder::read(ALvoid
*ptr
, ALuint count
)
105 unsigned char *dst
= reinterpret_cast<unsigned char*>(ptr
);
106 ALuint bytes
= count
* mChannels
* 2;
111 int ret
= mpg123_read(mMpg123
, dst
+total
, bytes
-total
, &got
);
112 if((ret
!= MPG123_OK
&& ret
!= MPG123_DONE
) || got
== 0)
116 if(ret
== MPG123_DONE
)
119 return total
/ mChannels
/ 2;
123 Mpg123DecoderFactory::Mpg123DecoderFactory()
128 if(mpg123_init() == MPG123_OK
)
133 Mpg123DecoderFactory::~Mpg123DecoderFactory()
141 SharedPtr
<Decoder
> Mpg123DecoderFactory::createDecoder(UniquePtr
<std::istream
> &file
)
146 mpg123_handle
*mpg123
= mpg123_new(0, 0);
149 if(mpg123_replace_reader_handle(mpg123
, r_read
, r_lseek
, 0) == MPG123_OK
&&
150 mpg123_open_handle(mpg123
, file
.get()) == MPG123_OK
)
155 if(mpg123_getformat(mpg123
, &srate
, &channels
, &enc
) == MPG123_OK
)
157 if((channels
== 1 || channels
== 2) && srate
> 0 &&
158 mpg123_format_none(mpg123
) == MPG123_OK
&&
159 mpg123_format(mpg123
, srate
, channels
, MPG123_ENC_SIGNED_16
) == MPG123_OK
)
162 return MakeShared
<Mpg123Decoder
>(std::move(file
), mpg123
, channels
, srate
);
165 mpg123_close(mpg123
);
167 mpg123_delete(mpg123
);