29#include <wx/checkbox.h>
30#include <wx/stattext.h>
39#error Requires libsndfile 1.0 or higher
42#include "../FileFormats.h"
56 struct id3_frame *id3_frame_new(
char const *);
57 id3_length_t id3_latin1_length(id3_latin1_t
const *);
58 void id3_latin1_decode(id3_latin1_t
const *, id3_ucs4_t *);
62#define DESC XO("WAV, AIFF, and other uncompressed types")
76 std::unique_ptr<ImportFileHandle>
Open(
122 memset(&info, 0,
sizeof(info));
126 if (filename.Lower().EndsWith(
wxT(
"mp3"))) {
142 if (f.Open(filename)) {
146 file.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, TRUE));
161 (info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_OGG) {
177 return std::make_unique<PCMImportFileHandle>(filename, std::move(file), info);
181 std::make_unique< PCMImportPlugin >()
185 SFFile &&file, SF_INFO info)
187 mFile(
std::move(file)),
190 wxASSERT(info.channels >= 0);
212using Unevaluated =
decltype(
214 XO(
"AIFF (Apple/SGI)")
215 ,
XO(
"AU (Sun/NeXT)")
216 ,
XO(
"AVR (Audio Visual Research)")
217 ,
XO(
"CAF (Apple Core Audio File)")
219 ,
XO(
"FLAC (FLAC Lossless Audio Codec)")
220 ,
XO(
"HTK (HMM Tool Kit)")
221 ,
XO(
"IFF (Amiga IFF/SVX8/SV16)")
222 ,
XO(
"MAT4 (GNU Octave 2.0 / Matlab 4.2)")
223 ,
XO(
"MAT5 (GNU Octave 2.1 / Matlab 5.0)")
224 ,
XO(
"MPC (Akai MPC 2k)")
225 ,
XO(
"OGG (OGG Container format)")
226 ,
XO(
"PAF (Ensoniq PARIS)")
227 ,
XO(
"PVF (Portable Voice Format)")
228 ,
XO(
"RAW (header-less)")
229 ,
XO(
"RF64 (RIFF 64)")
230 ,
XO(
"SD2 (Sound Designer II)")
231 ,
XO(
"SDS (Midi Sample Dump Standard)")
232 ,
XO(
"SF (Berkeley/IRCAM/CARL)")
233 ,
XO(
"VOC (Creative Labs)")
234 ,
XO(
"W64 (SoundFoundry WAVE 64)")
235 ,
XO(
"WAV (Microsoft)")
236 ,
XO(
"WAV (NIST Sphere)")
237 ,
XO(
"WAVEX (Microsoft)")
238 ,
XO(
"WVE (Psion Series 3)")
239 ,
XO(
"XI (FastTracker 2)")
242using Unevaluated2 =
decltype(
244 XO(
"Signed 8 bit PCM")
245 ,
XO(
"Signed 16 bit PCM")
246 ,
XO(
"Signed 24 bit PCM")
247 ,
XO(
"Signed 32 bit PCM")
248 ,
XO(
"Unsigned 8 bit PCM")
254 ,
XO(
"Microsoft ADPCM")
256 ,
XO(
"32kbs G721 ADPCM")
257 ,
XO(
"24kbs G723 ADPCM")
274 return mInfo.frames * mInfo.channels *
SAMPLE_SIZE(mFormat);
278struct id3_tag_deleter {
279 void operator () (id3_tag *p)
const {
if (p) id3_tag_delete(p); }
281using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
292 wxASSERT(
mFile.get());
300 auto iter = channels.begin();
301 for (
int c = 0; c <
mInfo.channels; ++iter, ++c)
305 auto fileTotalFrames =
307 auto maxBlockSize = channels.begin()->get()->GetMaxBlockSize();
316 using type =
decltype(maxBlockSize);
317 if (
mInfo.channels < 1)
318 return ProgressResult::Failed;
319 auto maxBlock =
std::min(maxBlockSize,
320 std::numeric_limits<type>::max() /
324 return ProgressResult::Failed;
327 wxASSERT(
mInfo.channels >= 0);
333 return ProgressResult::Failed;
336 decltype(fileTotalFrames) framescompleted = 0;
343 block = SFCall<sf_count_t>(sf_readf_short,
mFile.get(), (
short *)srcbuffer.
ptr(), block);
346 block = SFCall<sf_count_t>(sf_readf_float,
mFile.get(), (
float *)srcbuffer.
ptr(), block);
348 if(block < 0 || block > (
long)maxBlock) {
354 auto iter = channels.begin();
355 for(
int c=0; c<
mInfo.channels; ++iter, ++c) {
357 for(
int j=0; j<block; j++)
358 ((
short *)buffer.
ptr())[j] =
359 ((
short *)srcbuffer.
ptr())[
mInfo.channels*j+c];
362 for(
int j=0; j<block; j++)
363 ((
float *)buffer.
ptr())[j] =
364 ((
float *)srcbuffer.
ptr())[
mInfo.channels*j+c];
372 framescompleted += block;
376 framescompleted.as_long_long(),
377 fileTotalFrames.as_long_long()
389 for(
const auto &channel : channels)
392 if (!channels.empty())
393 outTracks.push_back(std::move(channels));
397 str = sf_get_string(
mFile.get(), SF_STR_TITLE);
402 str = sf_get_string(
mFile.get(), SF_STR_ALBUM);
407 str = sf_get_string(
mFile.get(), SF_STR_ARTIST);
412 str = sf_get_string(
mFile.get(), SF_STR_COMMENT);
417 str = sf_get_string(
mFile.get(), SF_STR_DATE);
422 str = sf_get_string(
mFile.get(), SF_STR_COPYRIGHT);
427 str = sf_get_string(
mFile.get(), SF_STR_SOFTWARE);
432 str = sf_get_string(
mFile.get(), SF_STR_TRACKNUMBER);
437 str = sf_get_string(
mFile.get(), SF_STR_GENRE);
442#if defined(USE_LIBID3TAG)
443 if (((
mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) ||
444 ((
mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)) {
460 if((
mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF)
461 len = wxUINT32_SWAP_ON_LE(len);
463 if (wxStricmp(
id,
"ID3 ") != 0) {
464 f.Seek(len + (len & 0x01), wxFromCurrent);
476 f.Read(buffer.get(), len);
477 tp.reset( id3_tag_parse(buffer.get(), len) );
485 bool have_year =
false;
486 for (
int i = 0; i < (int) tp->nframes; i++) {
487 struct id3_frame *frame = tp->frames[i];
503 if (strcmp(frame->id, ID3_FRAME_TITLE) == 0) {
506 else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0) {
509 else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0) {
512 else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0) {
515 else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0) {
528 else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0) {
531 else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) {
538 n =
UTF8CTOWX(frame->description).BeforeFirst(
wxT(
'/'));
541 const id3_ucs4_t *ustr = NULL;
544 ustr = id3_field_getfullstring(&frame->fields[3]);
546 else if (frame->nfields == 3) {
547 ustr = id3_field_getstring(&frame->fields[1]);
554 ustr = id3_field_getstring(&frame->fields[2]);
556 else if (frame->nfields >= 2) {
557 ustr = id3_field_getstrings(&frame->fields[1], 0);
566 if (!n.empty() && !v.empty()) {
const TranslatableString name
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::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...
An ImportFileHandle for data.
static sampleFormat ChooseFormat(sampleFormat effectiveFormat)
Choose appropriate format, which will not be narrower than the specified one.
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...
An ImportFileHandle for PCM data.
const TranslatableStrings & GetStreamInfo() override
ProgressResult Import(WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) 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.