14 class FlacDecoder
: public Decoder
{
15 UniquePtr
<std::istream
> mFile
;
17 FLAC__StreamDecoder
*mFlacFile
;
18 ChannelConfig mChannelConfig
;
19 SampleType mSampleType
;
24 Vector
<ALubyte
> mData
;
30 void CopySamples(ALubyte
*output
, ALuint todo
, const FLAC__Frame
*frame
, const FLAC__int32
*const buffer
[], ALuint offset
)
32 if(mSampleType
== SampleType::UInt8
)
34 int shift
= 8 - frame
->header
.bits_per_sample
;
35 ALubyte
*samples
= output
;
36 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
38 for(ALuint i
= 0;i
< todo
;i
++)
39 samples
[i
*frame
->header
.channels
+ c
] = ALubyte((buffer
[c
][offset
+i
]<<shift
) + 0x80);
42 else if(mSampleType
== SampleType::Int16
)
44 int shift
= 16 - frame
->header
.bits_per_sample
;
45 ALshort
*samples
= reinterpret_cast<ALshort
*>(output
);
48 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
50 for(ALuint i
= 0;i
< todo
;i
++)
51 samples
[i
*frame
->header
.channels
+ c
] = buffer
[c
][offset
+i
] << shift
;
57 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
59 for(ALuint i
= 0;i
< todo
;i
++)
60 samples
[i
*frame
->header
.channels
+ c
] = buffer
[c
][offset
+i
] >> shift
;
66 ALfloat scale
= 1.0f
/ (float)(1<<(frame
->header
.bits_per_sample
-1));
67 ALfloat
*samples
= reinterpret_cast<ALfloat
*>(output
);
68 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
70 for(ALuint i
= 0;i
< todo
;i
++)
71 samples
[i
*frame
->header
.channels
+ c
] = (ALfloat
)buffer
[c
][offset
+i
] * scale
;
76 static FLAC__StreamDecoderWriteStatus
WriteCallback(const FLAC__StreamDecoder
*, const FLAC__Frame
*frame
, const FLAC__int32
*const buffer
[], void *client_data
)
78 FlacDecoder
*self
= static_cast<FlacDecoder
*>(client_data
);
80 if(self
->mFrequency
== 0)
82 if(frame
->header
.channels
== 1)
83 self
->mChannelConfig
= ChannelConfig::Mono
;
84 else if(frame
->header
.channels
== 2)
85 self
->mChannelConfig
= ChannelConfig::Stereo
;
87 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
;
89 ALuint bps
= frame
->header
.bits_per_sample
;
90 if(bps
> 16 && Context::GetCurrent().isSupported(self
->mChannelConfig
, SampleType::Float32
))
92 self
->mSampleType
= SampleType::Float32
;
97 self
->mSampleType
= SampleType::Int16
;
102 self
->mSampleType
= SampleType::UInt8
;
106 self
->mFrameSize
= frame
->header
.channels
* bps
/8;
107 self
->mFrequency
= frame
->header
.sample_rate
;
110 ALubyte
*data
= self
->mOutBytes
+ self
->mOutLen
;
111 ALuint todo
= std::min
<ALuint
>((self
->mOutMax
-self
->mOutLen
) / self
->mFrameSize
,
112 frame
->header
.blocksize
);
113 self
->CopySamples(data
, todo
, frame
, buffer
, 0);
114 self
->mOutLen
+= self
->mFrameSize
* todo
;
116 if(todo
< frame
->header
.blocksize
)
118 ALuint offset
= todo
;
119 todo
= frame
->header
.blocksize
- todo
;
121 ALuint blocklen
= todo
* self
->mFrameSize
;
122 ALuint start
= self
->mData
.size();
124 self
->mData
.resize(start
+blocklen
);
125 data
= &self
->mData
[start
];
127 self
->CopySamples(data
, todo
, frame
, buffer
, offset
);
130 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
;
132 static void MetadataCallback(const FLAC__StreamDecoder
*,const FLAC__StreamMetadata
*,void*)
135 static void ErrorCallback(const FLAC__StreamDecoder
*,FLAC__StreamDecoderErrorStatus
,void*)
139 static FLAC__StreamDecoderReadStatus
ReadCallback(const FLAC__StreamDecoder
*, FLAC__byte buffer
[], size_t *bytes
, void *client_data
)
141 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
145 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
147 stream
->read(reinterpret_cast<char*>(buffer
), *bytes
);
148 *bytes
= stream
->gcount();
149 if(*bytes
== 0 && stream
->eof())
150 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
152 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
;
154 static FLAC__StreamDecoderSeekStatus
SeekCallback(const FLAC__StreamDecoder
*, FLAC__uint64 absolute_byte_offset
, void *client_data
)
156 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
159 if(!stream
->seekg(absolute_byte_offset
))
160 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
161 return FLAC__STREAM_DECODER_SEEK_STATUS_OK
;
163 static FLAC__StreamDecoderTellStatus
TellCallback(const FLAC__StreamDecoder
*, FLAC__uint64
*absolute_byte_offset
, void *client_data
)
165 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
168 *absolute_byte_offset
= stream
->tellg();
169 return FLAC__STREAM_DECODER_TELL_STATUS_OK
;
171 static FLAC__StreamDecoderLengthStatus
LengthCallback(const FLAC__StreamDecoder
*, FLAC__uint64
*stream_length
, void *client_data
)
173 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
176 std::streampos pos
= stream
->tellg();
177 if(stream
->seekg(0, std::ios_base::end
))
179 *stream_length
= stream
->tellg();
184 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
;
185 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK
;
187 static FLAC__bool
EofCallback(const FLAC__StreamDecoder
*, void *client_data
)
189 std::istream
*stream
= static_cast<FlacDecoder
*>(client_data
)->mFile
.get();
190 return stream
->eof() ? true : false;
195 : mFlacFile(nullptr), mChannelConfig(ChannelConfig::Mono
), mSampleType(SampleType::Int16
)
196 , mFrequency(0), mFrameSize(0), mSamplePos(0), mOutBytes(nullptr), mOutMax(0), mOutLen(0)
198 ~FlacDecoder() override final
;
200 bool open(UniquePtr
<std::istream
> &file
);
202 ALuint
getFrequency() const override final
;
203 ChannelConfig
getChannelConfig() const override final
;
204 SampleType
getSampleType() const override final
;
206 uint64_t getLength() const override final
;
207 uint64_t getPosition() const override final
;
208 bool seek(uint64_t pos
) override final
;
210 std::pair
<uint64_t,uint64_t> getLoopPoints() const override final
;
212 ALuint
read(ALvoid
*ptr
, ALuint count
) override final
;
215 FlacDecoder::~FlacDecoder()
219 FLAC__stream_decoder_finish(mFlacFile
);
220 FLAC__stream_decoder_delete(mFlacFile
);
226 bool FlacDecoder::open(UniquePtr
<std::istream
> &file
)
228 mFlacFile
= FLAC__stream_decoder_new();
231 mFile
= std::move(file
);
232 if(FLAC__stream_decoder_init_stream(mFlacFile
, ReadCallback
, SeekCallback
, TellCallback
, LengthCallback
, EofCallback
, WriteCallback
, MetadataCallback
, ErrorCallback
, this) == FLAC__STREAM_DECODER_INIT_STATUS_OK
)
236 if(FLAC__stream_decoder_process_single(mFlacFile
) == false ||
237 FLAC__stream_decoder_get_state(mFlacFile
) == FLAC__STREAM_DECODER_END_OF_STREAM
)
243 FLAC__stream_decoder_finish(mFlacFile
);
245 FLAC__stream_decoder_delete(mFlacFile
);
248 file
= std::move(mFile
);
255 ALuint
FlacDecoder::getFrequency() const
260 ChannelConfig
FlacDecoder::getChannelConfig() const
262 return mChannelConfig
;
265 SampleType
FlacDecoder::getSampleType() const
271 uint64_t FlacDecoder::getLength() const
273 return FLAC__stream_decoder_get_total_samples(mFlacFile
);
276 uint64_t FlacDecoder::getPosition() const
281 bool FlacDecoder::seek(uint64_t pos
)
283 if(!FLAC__stream_decoder_seek_absolute(mFlacFile
, pos
))
289 std::pair
<uint64_t,uint64_t> FlacDecoder::getLoopPoints() const
291 return std::make_pair(0, 0);
294 ALuint
FlacDecoder::read(ALvoid
*ptr
, ALuint count
)
296 mOutBytes
= reinterpret_cast<ALubyte
*>(ptr
);
298 mOutMax
= count
* mFrameSize
;
302 size_t rem
= std::min(mData
.size(), (size_t)mOutMax
);
303 memcpy(ptr
, &mData
[0], rem
);
305 mData
.erase(mData
.begin(), mData
.begin()+rem
);
308 while(mOutLen
< mOutMax
)
310 if(FLAC__stream_decoder_process_single(mFlacFile
) == false ||
311 FLAC__stream_decoder_get_state(mFlacFile
) == FLAC__STREAM_DECODER_END_OF_STREAM
)
314 ALuint ret
= mOutLen
/ mFrameSize
;
322 SharedPtr
<Decoder
> FlacDecoderFactory::createDecoder(UniquePtr
<std::istream
> &file
)
324 auto decoder
= MakeShared
<FlacDecoder
>();
325 if(!decoder
->open(file
)) decoder
.reset();