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());
295 auto fileTotalFrames =
306 if (
mInfo.channels < 1)
312 std::numeric_limits<type>::max() /
322 wxASSERT(
mInfo.channels >= 0);
334 decltype(fileTotalFrames) framescompleted = 0;
341 block = SFCall<sf_count_t>(sf_readf_short,
mFile.get(), (
short *)srcbuffer.
ptr(), block);
344 block = SFCall<sf_count_t>(sf_readf_float,
mFile.get(), (
float *)srcbuffer.
ptr(), block);
346 if(block < 0 || block > (
long)maxBlock) {
356 for(
int j=0; j<block; j++)
357 ((
short *)buffer.
ptr())[j] =
358 ((
short *)srcbuffer.
ptr())[
mInfo.channels*j+c];
361 for(
int j=0; j<block; j++)
362 ((
float *)buffer.
ptr())[j] =
363 ((
float *)srcbuffer.
ptr())[
mInfo.channels*j+c];
366 channel.AppendBuffer(
373 framescompleted += block;
375 if(fileTotalFrames > 0)
376 progressListener.
OnImportProgress(framescompleted.as_double() / fileTotalFrames.as_double());
390 str = sf_get_string(
mFile.get(), SF_STR_TITLE);
395 str = sf_get_string(
mFile.get(), SF_STR_ALBUM);
400 str = sf_get_string(
mFile.get(), SF_STR_ARTIST);
405 str = sf_get_string(
mFile.get(), SF_STR_COMMENT);
410 str = sf_get_string(
mFile.get(), SF_STR_DATE);
415 str = sf_get_string(
mFile.get(), SF_STR_COPYRIGHT);
420 str = sf_get_string(
mFile.get(), SF_STR_SOFTWARE);
425 str = sf_get_string(
mFile.get(), SF_STR_TRACKNUMBER);
430 str = sf_get_string(
mFile.get(), SF_STR_GENRE);
437 const std::vector<std::string> trustedDistributors {
"Muse Hub" };
439 outAcidTags.emplace(*acidTags);
441#if defined(USE_LIBID3TAG)
442 if (((
mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) ||
443 ((
mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)) {
459 if((
mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF)
460 len = wxUINT32_SWAP_ON_LE(len);
462 if (wxStricmp(
id,
"ID3 ") != 0) {
463 f.Seek(len + (len & 0x01), wxFromCurrent);
475 f.Read(buffer.get(), len);
476 tp.reset( id3_tag_parse(buffer.get(), len) );
484 bool have_year =
false;
485 for (
int i = 0; i < (int) tp->nframes; i++) {
486 struct id3_frame *frame = tp->frames[i];
502 if (strcmp(frame->id, ID3_FRAME_TITLE) == 0) {
505 else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0) {
508 else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0) {
511 else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0) {
514 else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0) {
527 else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0) {
530 else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) {
537 n =
UTF8CTOWX(frame->description).BeforeFirst(
wxT(
'/'));
540 const id3_ucs4_t *ustr = NULL;
543 ustr = id3_field_getfullstring(&frame->fields[3]);
545 else if (frame->nfields == 3) {
546 ustr = id3_field_getstring(&frame->fields[1]);
553 ustr = id3_field_getstring(&frame->fields[2]);
555 else if (frame->nfields >= 2) {
556 ustr = id3_field_getstrings(&frame->fields[1], 0);
565 if (!n.empty() && !v.empty()) {
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 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...
TrackListHolder CreateMany(size_t nChannels)
Creates tracks with project's default rate and format and the given number of channels.
A Track that contains audio waveform data.
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