33#error Requires libsndfile 1.0 or higher
51 struct id3_frame *id3_frame_new(
char const *);
52 id3_length_t id3_latin1_length(id3_latin1_t
const *);
53 void id3_latin1_decode(id3_latin1_t
const *, id3_ucs4_t *);
57#define DESC XO("WAV, AIFF, and other uncompressed types")
71 std::unique_ptr<ImportFileHandle>
Open(
87 std::optional<LibFileFormats::AcidizerTags>& outAcidTags)
override;
119 memset(&info, 0,
sizeof(info));
123 if (filename.Lower().EndsWith(
wxT(
"mp3"))) {
139 if (f.Open(filename)) {
143 file.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, TRUE));
158 (info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_OGG) {
174 return std::make_unique<PCMImportFileHandle>(filename, std::move(file), info);
178 std::make_unique< PCMImportPlugin >()
182 SFFile &&file, SF_INFO info)
184 mFile(
std::move(file)),
187 wxASSERT(info.channels >= 0);
209using Unevaluated =
decltype(
211 XO(
"AIFF (Apple/SGI)")
212 ,
XO(
"AU (Sun/NeXT)")
213 ,
XO(
"AVR (Audio Visual Research)")
214 ,
XO(
"CAF (Apple Core Audio File)")
216 ,
XO(
"FLAC (FLAC Lossless Audio Codec)")
217 ,
XO(
"HTK (HMM Tool Kit)")
218 ,
XO(
"IFF (Amiga IFF/SVX8/SV16)")
219 ,
XO(
"MAT4 (GNU Octave 2.0 / Matlab 4.2)")
220 ,
XO(
"MAT5 (GNU Octave 2.1 / Matlab 5.0)")
221 ,
XO(
"MPC (Akai MPC 2k)")
222 ,
XO(
"OGG (OGG Container format)")
223 ,
XO(
"PAF (Ensoniq PARIS)")
224 ,
XO(
"PVF (Portable Voice Format)")
225 ,
XO(
"RAW (header-less)")
226 ,
XO(
"RF64 (RIFF 64)")
227 ,
XO(
"SD2 (Sound Designer II)")
228 ,
XO(
"SDS (Midi Sample Dump Standard)")
229 ,
XO(
"SF (Berkeley/IRCAM/CARL)")
230 ,
XO(
"VOC (Creative Labs)")
231 ,
XO(
"W64 (SoundFoundry WAVE 64)")
232 ,
XO(
"WAV (Microsoft)")
233 ,
XO(
"WAV (NIST Sphere)")
234 ,
XO(
"WAVEX (Microsoft)")
235 ,
XO(
"WVE (Psion Series 3)")
236 ,
XO(
"XI (FastTracker 2)")
239using Unevaluated2 =
decltype(
241 XO(
"Signed 8 bit PCM")
242 ,
XO(
"Signed 16 bit PCM")
243 ,
XO(
"Signed 24 bit PCM")
244 ,
XO(
"Signed 32 bit PCM")
245 ,
XO(
"Unsigned 8 bit PCM")
251 ,
XO(
"Microsoft ADPCM")
253 ,
XO(
"32kbs G721 ADPCM")
254 ,
XO(
"24kbs G723 ADPCM")
271 return mInfo.frames * mInfo.channels *
SAMPLE_SIZE(mFormat);
275struct id3_tag_deleter {
276 void operator () (id3_tag *p)
const {
if (p) id3_tag_delete(p); }
278using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
284 std::optional<LibFileFormats::AcidizerTags>& outAcidTags)
290 wxASSERT(
mFile.get());
298 auto fileTotalFrames =
309 if (
mInfo.channels < 1)
315 std::numeric_limits<type>::max() /
325 wxASSERT(
mInfo.channels >= 0);
337 decltype(fileTotalFrames) framescompleted = 0;
344 block = SFCall<sf_count_t>(sf_readf_short,
mFile.get(), (
short *)srcbuffer.
ptr(), block);
347 block = SFCall<sf_count_t>(sf_readf_float,
mFile.get(), (
float *)srcbuffer.
ptr(), block);
349 if(block < 0 || block > (
long)maxBlock) {
359 for(
int j=0; j<block; j++)
360 ((
short *)buffer.
ptr())[j] =
361 ((
short *)srcbuffer.
ptr())[
mInfo.channels*j+c];
364 for(
int j=0; j<block; j++)
365 ((
float *)buffer.
ptr())[j] =
366 ((
float *)srcbuffer.
ptr())[
mInfo.channels*j+c];
369 channel.AppendBuffer(
376 framescompleted += block;
378 if(fileTotalFrames > 0)
379 progressListener.
OnImportProgress(framescompleted.as_double() / fileTotalFrames.as_double());
393 str = sf_get_string(
mFile.get(), SF_STR_TITLE);
398 str = sf_get_string(
mFile.get(), SF_STR_ALBUM);
403 str = sf_get_string(
mFile.get(), SF_STR_ARTIST);
408 str = sf_get_string(
mFile.get(), SF_STR_COMMENT);
413 str = sf_get_string(
mFile.get(), SF_STR_DATE);
418 str = sf_get_string(
mFile.get(), SF_STR_COPYRIGHT);
423 str = sf_get_string(
mFile.get(), SF_STR_SOFTWARE);
428 str = sf_get_string(
mFile.get(), SF_STR_TRACKNUMBER);
433 str = sf_get_string(
mFile.get(), SF_STR_GENRE);
440 const std::vector<std::string> trustedDistributors {
"Muse Hub" };
442 outAcidTags.emplace(*acidTags);
444#if defined(USE_LIBID3TAG)
445 if (((
mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) ||
446 ((
mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)) {
462 if((
mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF)
463 len = wxUINT32_SWAP_ON_LE(len);
465 if (wxStricmp(
id,
"ID3 ") != 0) {
466 f.Seek(len + (len & 0x01), wxFromCurrent);
478 f.Read(buffer.get(), len);
479 tp.reset( id3_tag_parse(buffer.get(), len) );
487 bool have_year =
false;
488 for (
int i = 0; i < (int) tp->nframes; i++) {
489 struct id3_frame *frame = tp->frames[i];
505 if (strcmp(frame->id, ID3_FRAME_TITLE) == 0) {
508 else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0) {
511 else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0) {
514 else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0) {
517 else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0) {
530 else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0) {
533 else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) {
540 n =
UTF8CTOWX(frame->description).BeforeFirst(
wxT(
'/'));
543 const id3_ucs4_t *ustr = NULL;
546 ustr = id3_field_getfullstring(&frame->fields[3]);
548 else if (frame->nfields == 3) {
549 ustr = id3_field_getstring(&frame->fields[1]);
556 ustr = id3_field_getstring(&frame->fields[2]);
558 else if (frame->nfields >= 2) {
559 ustr = id3_field_getstrings(&frame->fields[1], 0);
568 if (!n.empty() && !v.empty()) {
const TranslatableString name
static Importer::RegisteredImportPlugin registered
The interface that all file import "plugins" (if you want to call them that) must implement....
std::vector< std::shared_ptr< Track > > TrackHolders
std::unique_ptr< Character[], freer > MallocString
std::vector< TranslatableString > TranslatableStrings
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...
bool IsStopped() const noexcept
FilePath GetFilename() const override
bool IsCancelled() const noexcept
unsigned long long ByteCount
Base class for FlacImportPlugin, LOFImportPlugin, MP3ImportPlugin, OggImportPlugin and PCMImportPlugi...
Interface used to report on import state and progress.
virtual void OnImportResult(ImportResult result)=0
Used to report on import result for file handle passed as argument to OnImportFileOpened.
virtual void OnImportProgress(double progress)=0
static std::shared_ptr< WaveTrack > NewWaveTrack(WaveTrackFactory &trackFactory, unsigned nChannels, sampleFormat effectiveFormat, double rate)
static sampleFormat ChooseFormat(sampleFormat effectiveFormat)
Choose appropriate format, which will not be narrower than the specified one.
static void ForEachChannel(TrackList &trackList, const std::function< void(WaveChannel &)> &op)
Iterates over channels in each wave track from the list.
static void FinalizeImport(TrackHolders &outTracks, const std::vector< std::shared_ptr< WaveTrack > > &importedStreams)
Flushes the given channels and moves them to outTracks.
An ImportFileHandle for PCM data.
const TranslatableStrings & GetStreamInfo() override
void Import(ImportProgressListener &progressListener, WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags, std::optional< LibFileFormats::AcidizerTags > &outAcidTags) override
void SetStreamUsage(wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
wxInt32 GetStreamCount() override
TranslatableString GetFileDescription() override
ByteCount GetFileUncompressedBytes() override
PCMImportFileHandle(const FilePath &name, SFFile &&file, SF_INFO info)
sampleFormat mEffectiveFormat
An ImportPlugin for PCM data.
wxString GetPluginStringID() override
TranslatableString GetPluginFormatDescription() override
std::unique_ptr< ImportFileHandle > Open(const FilePath &Filename, AudacityProject *) override
SampleBuffer & Allocate(size_t count, sampleFormat format)
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...
Positions or offsets within audio files need a wide type.
std::optional< LibFileFormats::AcidizerTags > GetAcidizerTags(SNDFILE &file, const std::vector< std::string > &trustedDistributors)
Get the Acidizer tags from a file if from a trusted distributor.
constexpr auto maxBlockSize