14 class FlacDecoder final
: public Decoder
{
15 UniquePtr
<std::istream
> mFile
;
17 FLAC__StreamDecoder
*mFlacFile
;
18 ChannelConfig mChannelConfig
;
19 SampleType mSampleType
;
23 Vector
<ALubyte
> mData
;
29 void CopySamples(ALubyte
*output
, ALuint todo
, const FLAC__Frame
*frame
, const FLAC__int32
*const buffer
[], ALuint offset
)
31 if(mSampleType
== SampleType::UInt8
)
33 int shift
= 8 - frame
->header
.bits_per_sample
;
34 ALubyte
*samples
= output
;
35 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
37 for(ALuint i
= 0;i
< todo
;i
++)
38 samples
[i
*frame
->header
.channels
+ c
] = ALubyte((buffer
[c
][offset
+i
]<<shift
) + 0x80);
41 else if(mSampleType
== SampleType::Int16
)
43 int shift
= 16 - frame
->header
.bits_per_sample
;
44 ALshort
*samples
= reinterpret_cast<ALshort
*>(output
);
47 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
49 for(ALuint i
= 0;i
< todo
;i
++)
50 samples
[i
*frame
->header
.channels
+ c
] = buffer
[c
][offset
+i
] << shift
;
56 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
58 for(ALuint i
= 0;i
< todo
;i
++)
59 samples
[i
*frame
->header
.channels
+ c
] = buffer
[c
][offset
+i
] >> shift
;
65 ALfloat scale
= 1.0f
/ (float)(1<<(frame
->header
.bits_per_sample
-1));
66 ALfloat
*samples
= reinterpret_cast<ALfloat
*>(output
);
67 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
69 for(ALuint i
= 0;i
< todo
;i
++)
70 samples
[i
*frame
->header
.channels
+ c
] = (ALfloat
)buffer
[c
][offset
+i
] * scale
;
75 static FLAC__StreamDecoderWriteStatus
WriteCallback(const FLAC__StreamDecoder
*, const FLAC__Frame
*frame
, const FLAC__int32
*const buffer
[], void *client_data
)
77 FlacDecoder
*self
= static_cast<FlacDecoder
*>(client_data
);
79 if(self
->mFrequency
== 0)
81 if(frame
->header
.channels
== 1)
82 self
->mChannelConfig
= ChannelConfig::Mono
;
83 else if(frame
->header
.channels
== 2)
84 self
->mChannelConfig
= ChannelConfig::Stereo
;
86 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
;
88 ALuint bps
= frame
->header
.bits_per_sample
;
89 if(bps
> 16 && Context::GetCurrent().isSupported(self
->mChannelConfig
, SampleType::Float32
))
91 self
->mSampleType
= SampleType::Float32
;
96 self
->mSampleType
= SampleType::Int16
;
101 self
->mSampleType
= SampleType::UInt8
;
105 self
->mFrameSize
= frame
->header
.channels
* bps
/8;
106 self
->mFrequency
= frame
->header
.sample_rate
;
109 ALubyte
*data
= self
->mOutBytes
+ self
->mOutLen
;
110 ALuint todo
= std::min
<ALuint
>((self
->mOutMax
-self
->mOutLen
) / self
->mFrameSize
,
111 frame
->header
.blocksize
);
112 self
->CopySamples(data
, todo
, frame
, buffer
, 0);
113 self
->mOutLen
+= self
->mFrameSize
* todo
;
115 if(todo
< frame
->header
.blocksize
)
117 ALuint offset
= todo
;
118 todo
= frame
->header
.blocksize
- todo
;
120 ALuint blocklen
= todo
* self
->mFrameSize
;
121 ALuint start
= self
->mData
.size();
123 self
->mData
.resize(start
+blocklen
);
124 data
= &self
->mData
[start
];
126 self
->CopySamples(data
, todo
, frame
, buffer
, offset
);
129 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
;
131 static void MetadataCallback(const FLAC__StreamDecoder
*,const FLAC__StreamMetadata
*,void*)
134 static void ErrorCallback(const FLAC__StreamDecoder
*,FLAC__StreamDecoderErrorStatus
,void*)
138 static FLAC__StreamDecoderReadStatus
ReadCallback(const FLAC__StreamDecoder
*, FLAC__byte buffer
[], size_t *bytes
, void *client_data
)
140 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
144 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
146 stream
->read(reinterpret_cast<char*>(buffer
), *bytes
);
147 *bytes
= stream
->gcount();
148 if(*bytes
== 0 && stream
->eof())
149 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
151 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
;
153 static FLAC__StreamDecoderSeekStatus
SeekCallback(const FLAC__StreamDecoder
*, FLAC__uint64 absolute_byte_offset
, void *client_data
)
155 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
158 if(!stream
->seekg(absolute_byte_offset
))
159 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
160 return FLAC__STREAM_DECODER_SEEK_STATUS_OK
;
162 static FLAC__StreamDecoderTellStatus
TellCallback(const FLAC__StreamDecoder
*, FLAC__uint64
*absolute_byte_offset
, void *client_data
)
164 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
167 *absolute_byte_offset
= stream
->tellg();
168 return FLAC__STREAM_DECODER_TELL_STATUS_OK
;
170 static FLAC__StreamDecoderLengthStatus
LengthCallback(const FLAC__StreamDecoder
*, FLAC__uint64
*stream_length
, void *client_data
)
172 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
175 std::streampos pos
= stream
->tellg();
176 if(stream
->seekg(0, std::ios_base::end
))
178 *stream_length
= stream
->tellg();
183 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
;
184 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK
;
186 static FLAC__bool
EofCallback(const FLAC__StreamDecoder
*, void *client_data
)
188 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
189 return stream
->eof() ? true : false;
194 : mFlacFile(nullptr), mChannelConfig(ChannelConfig::Mono
), mSampleType(SampleType::Int16
)
195 , mFrequency(0), mFrameSize(0), mOutBytes(nullptr), mOutMax(0), mOutLen(0)
197 ~FlacDecoder() override
;
199 bool open(UniquePtr
<std::istream
> &file
);
201 ALuint
getFrequency() const override
;
202 ChannelConfig
getChannelConfig() const override
;
203 SampleType
getSampleType() const override
;
205 uint64_t getLength() const override
;
206 bool seek(uint64_t pos
) override
;
208 std::pair
<uint64_t,uint64_t> getLoopPoints() const override
;
210 ALuint
read(ALvoid
*ptr
, ALuint count
) override
;
213 FlacDecoder::~FlacDecoder()
217 FLAC__stream_decoder_finish(mFlacFile
);
218 FLAC__stream_decoder_delete(mFlacFile
);
224 bool FlacDecoder::open(UniquePtr
<std::istream
> &file
)
226 mFlacFile
= FLAC__stream_decoder_new();
229 mFile
= std::move(file
);
230 if(FLAC__stream_decoder_init_stream(mFlacFile
, ReadCallback
, SeekCallback
, TellCallback
, LengthCallback
, EofCallback
, WriteCallback
, MetadataCallback
, ErrorCallback
, this) == FLAC__STREAM_DECODER_INIT_STATUS_OK
)
234 if(FLAC__stream_decoder_process_single(mFlacFile
) == false ||
235 FLAC__stream_decoder_get_state(mFlacFile
) == FLAC__STREAM_DECODER_END_OF_STREAM
)
241 FLAC__stream_decoder_finish(mFlacFile
);
243 FLAC__stream_decoder_delete(mFlacFile
);
246 file
= std::move(mFile
);
253 ALuint
FlacDecoder::getFrequency() const
258 ChannelConfig
FlacDecoder::getChannelConfig() const
260 return mChannelConfig
;
263 SampleType
FlacDecoder::getSampleType() const
269 uint64_t FlacDecoder::getLength() const
271 return FLAC__stream_decoder_get_total_samples(mFlacFile
);
274 bool FlacDecoder::seek(uint64_t pos
)
276 if(!FLAC__stream_decoder_seek_absolute(mFlacFile
, pos
))
281 std::pair
<uint64_t,uint64_t> FlacDecoder::getLoopPoints() const
283 return std::make_pair(0, 0);
286 ALuint
FlacDecoder::read(ALvoid
*ptr
, ALuint count
)
288 mOutBytes
= reinterpret_cast<ALubyte
*>(ptr
);
290 mOutMax
= count
* mFrameSize
;
294 size_t rem
= std::min(mData
.size(), (size_t)mOutMax
);
295 memcpy(ptr
, mData
.data(), rem
);
297 mData
.erase(mData
.begin(), mData
.begin()+rem
);
300 while(mOutLen
< mOutMax
)
302 if(FLAC__stream_decoder_process_single(mFlacFile
) == false ||
303 FLAC__stream_decoder_get_state(mFlacFile
) == FLAC__STREAM_DECODER_END_OF_STREAM
)
306 return mOutLen
/ mFrameSize
;
310 SharedPtr
<Decoder
> FlacDecoderFactory::createDecoder(UniquePtr
<std::istream
> &file
)
312 auto decoder
= MakeShared
<FlacDecoder
>();
313 if(!decoder
->open(file
)) decoder
.reset();