44#define FLAC_HEADER "fLaC"
46#define DESC XO("FLAC files")
56 std::make_unique<UnusableImportPlugin>
65#include "FLAC++/decoder.h"
78#if !defined FLACPP_API_VERSION_CURRENT || FLACPP_API_VERSION_CURRENT < 6
94 set_metadata_ignore_all();
95 set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT);
96 set_metadata_respond(FLAC__METADATA_TYPE_STREAMINFO);
109 FLAC__StreamDecoderWriteStatus
write_callback(
const FLAC__Frame *frame,
110 const FLAC__int32 *
const buffer[])
override;
112 void error_callback(FLAC__StreamDecoderErrorStatus status)
override;
128 std::unique_ptr<ImportFileHandle>
Open(
145 Tags *tags)
override;
175 switch (metadata->type)
177 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
178 for (FLAC__uint32 i = 0; i < metadata->data.vorbis_comment.num_comments; i++) {
179 mComments.push_back(
UTF8CTOWX((
char *)metadata->data.vorbis_comment.comments[i].entry));
183 case FLAC__METADATA_TYPE_STREAMINFO:
200 case FLAC__METADATA_TYPE_PADDING:
201 case FLAC__METADATA_TYPE_APPLICATION:
202 case FLAC__METADATA_TYPE_SEEKTABLE:
203 case FLAC__METADATA_TYPE_CUESHEET:
204 case FLAC__METADATA_TYPE_PICTURE:
205 case FLAC__METADATA_TYPE_UNDEFINED:
237 const FLAC__int32 *
const buffer[])
240 return GuardedCall< FLAC__StreamDecoderWriteStatus > ( [&] {
245 if (frame->header.bits_per_sample <= 16) {
246 if (frame->header.bits_per_sample == 8) {
247 for (unsigned int s = 0; s < frame->header.blocksize; s++) {
248 tmp[s] = buffer[chn][s] << 8;
251 for (unsigned int s = 0; s < frame->header.blocksize; s++) {
252 tmp[s] = buffer[chn][s];
258 frame->header.blocksize, 1,
264 frame->header.blocksize, 1,
274 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
277 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
294 if (!binaryFile.Open(filename)) {
302 id3_byte_t query[ID3_TAG_QUERYSIZE];
303 cnt = binaryFile.Read(query,
sizeof(query));
304 cnt = id3_tag_query(query, cnt);
305 binaryFile.Seek(cnt);
309 cnt = binaryFile.Read(buf, 4);
312 if (cnt == wxInvalidOffset || strncmp(buf,
FLAC_HEADER, 4) != 0) {
318 auto handle = std::make_unique<FLACImportFileHandle>(filename);
320 bool success = handle->Init();
326 return std::move(handle);
330 std::make_unique< FLACImportPlugin >()
336 mStreamInfoDone(false),
341 mFile = std::make_unique<MyFLACFile>(
this);
351 mFile->set_metadata_respond(FLAC__METADATA_TYPE_STREAMINFO);
352 mFile->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT);
353 FLAC::Decoder::File::State state =
mFile->init();
354 if (state != FLAC__FILE_DECODER_OK) {
371 if (result != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
375 mFile->process_until_end_of_metadata();
378 state =
mFile->get_state();
379 if (state != FLAC__FILE_DECODER_OK) {
384 if (
mFile->get_state() > FLAC__STREAM_DECODER_READ_FRAME) {
389 if (!
mFile->is_valid() ||
mFile->get_was_error()) {
430 bool res = (
mFile->process_until_end_of_file() != 0);
432 bool res = (
mFile->process_until_end_of_stream() != 0);
444 outTracks.push_back(std::move(
mChannels));
447 wxString description;
449 size_t cnt =
mFile->mComments.size();
452 for (
size_t c = 0; c < cnt; c++) {
453 wxString
name =
mFile->mComments[c].BeforeFirst(
wxT(
'='));
454 wxString value =
mFile->mComments[c].AfterFirst(
wxT(
'='));
455 wxString upper =
name.Upper();
458 if (value.length() == 4 && value.ToLong(&val)) {
462 else if (upper ==
wxT(
"COMMENT") || upper ==
wxT(
"COMMENTS")) {
466 else if (upper ==
wxT(
"DESCRIPTION")) {
473 if (comment.empty()) {
474 comment = description;
476 if (!comment.empty()) {
SimpleGuard< R > MakeSimpleGuard(R value) noexcept(noexcept(SimpleGuard< R >{ value }))
Convert a value to a handler function returning that value, suitable for GuardedCall<R>
const TranslatableString name
wxArrayStringEx FileExtensions
std::vector< std::shared_ptr< WaveTrack > > NewChannelGroup
std::vector< std::vector< std::shared_ptr< WaveTrack > > > TrackHolders
static Importer::RegisteredImportPlugin registered
The interface that all file import "plugins" (if you want to call them that) must implement....
std::vector< TranslatableString > TranslatableStrings
Append([](My &table) -> Registry::BaseItemPtr { if(WaveTrackSubViews::slots() > 1) return std::make_unique< Entry >("MultiView", Entry::CheckItem, OnMultiViewID, XXO("&Multi-view"), POPUP_MENU_FN(OnMultiView), table, [](PopupMenuHandler &handler, wxMenu &menu, int id){ auto &table=static_cast< WaveTrackMenuTable & >(handler);auto &track=table.FindWaveTrack();const auto &view=WaveTrackView::Get(track);menu.Check(id, view.GetMultiView());});else return nullptr;})
This simplifies arrays of arrays, each array separately allocated with NEW[] But it might be better t...
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
An ImportFileHandle for FLAC data.
ProgressResult Import(WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override
FLACImportFileHandle(const FilePath &name)
void SetStreamUsage(wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
NewChannelGroup mChannels
FLAC__uint64 mSamplesDone
std::unique_ptr< MyFLACFile > mFile
const TranslatableStrings & GetStreamInfo() override
TranslatableString GetFileDescription() override
ByteCount GetFileUncompressedBytes() override
unsigned long mBitsPerSample
ProgressResult mUpdateResult
unsigned long mNumChannels
unsigned long mSampleRate
wxInt32 GetStreamCount() override
An ImportPlugin for FLAC data.
wxString GetPluginStringID() override
std::unique_ptr< ImportFileHandle > Open(const FilePath &Filename, AudacityProject *) override
TranslatableString GetPluginFormatDescription() override
An ImportFileHandle for data.
unsigned long long ByteCount
std::unique_ptr< ProgressDialog > mProgress
std::shared_ptr< WaveTrack > NewWaveTrack(WaveTrackFactory &trackFactory, sampleFormat effectiveFormat, double rate)
Build a wave track with appropriate format, which will not be narrower than the specified one.
Base class for FlacImportPlugin, LOFImportPlugin, MP3ImportPlugin, OggImportPlugin and PCMImportPlugi...
void error_callback(FLAC__StreamDecoderErrorStatus status) override
MyFLACFile(FLACImportFileHandle *handle)
FLAC__StreamDecoderWriteStatus write_callback(const FLAC__Frame *frame, const FLAC__int32 *const buffer[]) override
bool get_was_error() const
FLACImportFileHandle * mFile
void metadata_callback(const FLAC__StreamMetadata *metadata) override
Holds a msgid for the translation catalog; may also bind format arguments.
Used to create or clone a WaveTrack, with appropriate context from the project that will own the trac...
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.