Audacity  3.0.3
ImportPCM.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  ImportPCM.cpp
6 
7  Dominic Mazzoni
8  Leland Lucius
9 
10 *//****************************************************************//****************************************************************//*******************************************************************/
21 
22 
23 
24 #include "Import.h"
25 #include "../Tags.h"
26 
27 #include <wx/wx.h>
28 #include <wx/string.h>
29 #include <wx/utils.h>
30 #include <wx/intl.h>
31 #include <wx/ffile.h>
32 #include <wx/sizer.h>
33 #include <wx/checkbox.h>
34 #include <wx/button.h>
35 #include <wx/stattext.h>
36 
37 #include "sndfile.h"
38 
39 #include "../ShuttleGui.h"
40 
41 #include "../widgets/ProgressDialog.h"
42 
43 #ifndef SNDFILE_1
44 #error Requires libsndfile 1.0 or higher
45 #endif
46 
47 #include "../FileFormats.h"
48 #include "Prefs.h"
49 #include "../ShuttleGui.h"
50 #include "../WaveTrack.h"
51 #include "ImportPlugin.h"
52 
53 #include <algorithm>
54 
55 #ifdef USE_LIBID3TAG
56  #include <id3tag.h>
57  // DM: the following functions were supposed to have been
58  // included in id3tag.h - should be fixed in the next release
59  // of mad.
60  extern "C" {
61  struct id3_frame *id3_frame_new(char const *);
62  id3_length_t id3_latin1_length(id3_latin1_t const *);
63  void id3_latin1_decode(id3_latin1_t const *, id3_ucs4_t *);
64  }
65 #endif
66 
67 #define DESC XO("WAV, AIFF, and other uncompressed types")
68 
69 class PCMImportPlugin final : public ImportPlugin
70 {
71 public:
74  {
75  }
76 
78 
79  wxString GetPluginStringID() override { return wxT("libsndfile"); }
81  std::unique_ptr<ImportFileHandle> Open(
82  const FilePath &Filename, AudacityProject*) override;
83 };
84 
85 
87 {
88 public:
89  PCMImportFileHandle(const FilePath &name, SFFile &&file, SF_INFO info);
91 
94  ProgressResult Import(WaveTrackFactory *trackFactory, TrackHolders &outTracks,
95  Tags *tags) override;
96 
97  wxInt32 GetStreamCount() override { return 1; }
98 
100  {
101  static TranslatableStrings empty;
102  return empty;
103  }
104 
105  void SetStreamUsage(wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
106  {}
107 
108 private:
110  const SF_INFO mInfo;
112 };
113 
115 {
116  return DESC;
117 }
118 
119 std::unique_ptr<ImportFileHandle> PCMImportPlugin::Open(
120  const FilePath &filename, AudacityProject*)
121 {
122  SF_INFO info;
123  wxFile f; // will be closed when it goes out of scope
124  SFFile file;
125 
126  memset(&info, 0, sizeof(info));
127 
128 
129 #ifdef __WXGTK__
130  if (filename.Lower().EndsWith(wxT("mp3"))) {
131  // There is a bug in libsndfile where mp3s with duplicated metadata tags
132  // will crash libsndfile and thus audacity.
133  // We have patched the lib-src version of libsndfile, but
134  // for linux the user can build against the system libsndfile which
135  // still has this bug.
136  // This happens in sf_open_fd, which is the very first point of
137  // interaction with libsndfile, so the only workaround is to hardcode
138  // ImportPCM to not handle .mp3. Of course, this will still fail for mp3s
139  // that are mislabeled with a .wav or other extension.
140  // So, in the future we may want to write a simple parser to detect mp3s here.
141  return NULL;
142  }
143 #endif
144 
145 
146  if (f.Open(filename)) {
147  // Even though there is an sf_open() that takes a filename, use the one that
148  // takes a file descriptor since wxWidgets can open a file with a Unicode name and
149  // libsndfile can't (under Windows).
150  file.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, TRUE));
151  }
152 
153  // The file descriptor is now owned by "file", so we must tell "f" to leave
154  // it alone. The file descriptor is closed by the destructor of file even if an error
155  // occurs.
156  f.Detach();
157 
158  if (!file) {
159  // TODO: Handle error
160  //char str[1000];
161  //sf_error_str((SNDFILE *)NULL, str, 1000);
162 
163  return nullptr;
164  } else if (file &&
165  (info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_OGG) {
166  // mchinen 15.1.2012 - disallowing libsndfile to handle
167  // ogg files because seeking is broken at this date (very slow,
168  // seeks from beginning of file each seek).
169  // This was said by Erik (libsndfile maintainer).
170  // Note that this won't apply to our local libsndfile, so only
171  // linux builds that use --with-libsndfile=system are affected,
172  // as our local libsndfile doesn't do OGG.
173  // In particular ubuntu 10.10 and 11.04 are known to be affected
174  // When the bug is fixed, we can check version to avoid only
175  // the broken builds.
176 
177  return nullptr;
178  }
179 
180  // Success, so now transfer the duty to close the file from "file".
181  return std::make_unique<PCMImportFileHandle>(filename, std::move(file), info);
182 }
183 
185  std::make_unique< PCMImportPlugin >()
186 };
187 
189  SFFile &&file, SF_INFO info)
191  mFile(std::move(file)),
192  mInfo(info)
193 {
194  wxASSERT(info.channels >= 0);
195 
196  //
197  // Figure out the format to use.
198  //
199  // In general, go with the user's preferences. However, if
200  // the file is higher-quality, go with a format which preserves
201  // the quality of the original file.
202  //
203 
204  mFormat =
206 }
207 
209 {
210  // Library strings
211  // See the major_formats and subtype_formats tables in command.c in
212  // libsndfile for this list of possibilities
213 
214 using Unevaluated = decltype(
215  /* major_formats */
216  XO("AIFF (Apple/SGI)")
217  , XO("AU (Sun/NeXT)")
218  , XO("AVR (Audio Visual Research)")
219  , XO("CAF (Apple Core Audio File)")
220  /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
221  , XO("FLAC (FLAC Lossless Audio Codec)")
222  , XO("HTK (HMM Tool Kit)")
223  , XO("IFF (Amiga IFF/SVX8/SV16)")
224  , XO("MAT4 (GNU Octave 2.0 / Matlab 4.2)")
225  , XO("MAT5 (GNU Octave 2.1 / Matlab 5.0)")
226  , XO("MPC (Akai MPC 2k)")
227  , XO("OGG (OGG Container format)")
228  , XO("PAF (Ensoniq PARIS)")
229  , XO("PVF (Portable Voice Format)")
230  , XO("RAW (header-less)")
231  , XO("RF64 (RIFF 64)")
232  , XO("SD2 (Sound Designer II)")
233  , XO("SDS (Midi Sample Dump Standard)")
234  , XO("SF (Berkeley/IRCAM/CARL)")
235  , XO("VOC (Creative Labs)")
236  , XO("W64 (SoundFoundry WAVE 64)")
237  , XO("WAV (Microsoft)")
238  , XO("WAV (NIST Sphere)")
239  , XO("WAVEX (Microsoft)")
240  , XO("WVE (Psion Series 3)")
241  , XO("XI (FastTracker 2)")
242 );
243 
244 using Unevaluated2 = decltype(
245  /* subtype_formats */
246  XO("Signed 8 bit PCM")
247  , XO("Signed 16 bit PCM")
248  , XO("Signed 24 bit PCM")
249  , XO("Signed 32 bit PCM")
250  , XO("Unsigned 8 bit PCM")
251  , XO("32 bit float")
252  , XO("64 bit float")
253  , XO("U-Law")
254  , XO("A-Law")
255  , XO("IMA ADPCM")
256  , XO("Microsoft ADPCM")
257  , XO("GSM 6.10")
258  , XO("32kbs G721 ADPCM")
259  , XO("24kbs G723 ADPCM")
260  , XO("12 bit DWVW")
261  , XO("16 bit DWVW")
262  , XO("24 bit DWVW")
263  , XO("VOX ADPCM")
264  , XO("16 bit DPCM")
265  , XO("8 bit DPCM")
266  , XO("Vorbis")
267 );
268 
269  auto untranslated = SFCall<wxString>(sf_header_name, mInfo.format);
270  return TranslatableString{
271  untranslated, {} };
272 }
273 
275 {
276  return mInfo.frames * mInfo.channels * SAMPLE_SIZE(mFormat);
277 }
278 
279 #ifdef USE_LIBID3TAG
280 struct id3_tag_deleter {
281  void operator () (id3_tag *p) const { if (p) id3_tag_delete(p); }
282 };
283 using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
284 #endif
285 
286 using NewChannelGroup = std::vector< std::shared_ptr<WaveTrack> >;
287 
289  TrackHolders &outTracks,
290  Tags *tags)
291 {
292  outTracks.clear();
293 
294  wxASSERT(mFile.get());
295 
296  CreateProgress();
297 
298  NewChannelGroup channels(mInfo.channels);
299 
300  {
301  // iter not used outside this scope.
302  auto iter = channels.begin();
303  for (int c = 0; c < mInfo.channels; ++iter, ++c)
304  *iter = NewWaveTrack(*trackFactory, mFormat, mInfo.samplerate);
305  }
306 
307  auto fileTotalFrames =
308  (sampleCount)mInfo.frames; // convert from sf_count_t
309  auto maxBlockSize = channels.begin()->get()->GetMaxBlockSize();
310  auto updateResult = ProgressResult::Cancelled;
311 
312  {
313  // Otherwise, we're in the "copy" mode, where we read in the actual
314  // samples from the file and store our own local copy of the
315  // samples in the tracks.
316 
317  // PRL: guard against excessive memory buffer allocation in case of many channels
318  using type = decltype(maxBlockSize);
319  if (mInfo.channels < 1)
320  return ProgressResult::Failed;
321  auto maxBlock = std::min(maxBlockSize,
322  std::numeric_limits<type>::max() /
323  (mInfo.channels * SAMPLE_SIZE(mFormat))
324  );
325  if (maxBlock < 1)
326  return ProgressResult::Failed;
327 
328  SampleBuffer srcbuffer, buffer;
329  wxASSERT(mInfo.channels >= 0);
330  while (NULL == srcbuffer.Allocate(maxBlock * mInfo.channels, mFormat).ptr() ||
331  NULL == buffer.Allocate(maxBlock, mFormat).ptr())
332  {
333  maxBlock /= 2;
334  if (maxBlock < 1)
335  return ProgressResult::Failed;
336  }
337 
338  decltype(fileTotalFrames) framescompleted = 0;
339 
340  long block;
341  do {
342  block = maxBlock;
343 
344  if (mFormat == int16Sample)
345  block = SFCall<sf_count_t>(sf_readf_short, mFile.get(), (short *)srcbuffer.ptr(), block);
346  //import 24 bit int as float and have the append function convert it. This is how PCMAliasBlockFile worked too.
347  else
348  block = SFCall<sf_count_t>(sf_readf_float, mFile.get(), (float *)srcbuffer.ptr(), block);
349 
350  if(block < 0 || block > (long)maxBlock) {
351  wxASSERT(false);
352  block = maxBlock;
353  }
354 
355  if (block) {
356  auto iter = channels.begin();
357  for(int c=0; c<mInfo.channels; ++iter, ++c) {
358  if (mFormat==int16Sample) {
359  for(int j=0; j<block; j++)
360  ((short *)buffer.ptr())[j] =
361  ((short *)srcbuffer.ptr())[mInfo.channels*j+c];
362  }
363  else {
364  for(int j=0; j<block; j++)
365  ((float *)buffer.ptr())[j] =
366  ((float *)srcbuffer.ptr())[mInfo.channels*j+c];
367  }
368 
369  iter->get()->Append(buffer.ptr(), (mFormat == int16Sample)?int16Sample:floatSample, block);
370  }
371  framescompleted += block;
372  }
373 
374  updateResult = mProgress->Update(
375  framescompleted.as_long_long(),
376  fileTotalFrames.as_long_long()
377  );
378  if (updateResult != ProgressResult::Success)
379  break;
380 
381  } while (block > 0);
382  }
383 
384  if (updateResult == ProgressResult::Failed || updateResult == ProgressResult::Cancelled) {
385  return updateResult;
386  }
387 
388  for(const auto &channel : channels)
389  channel->Flush();
390 
391  if (!channels.empty())
392  outTracks.push_back(std::move(channels));
393 
394  const char *str;
395 
396  str = sf_get_string(mFile.get(), SF_STR_TITLE);
397  if (str) {
398  tags->SetTag(TAG_TITLE, UTF8CTOWX(str));
399  }
400 
401  str = sf_get_string(mFile.get(), SF_STR_ALBUM);
402  if (str) {
403  tags->SetTag(TAG_ALBUM, UTF8CTOWX(str));
404  }
405 
406  str = sf_get_string(mFile.get(), SF_STR_ARTIST);
407  if (str) {
408  tags->SetTag(TAG_ARTIST, UTF8CTOWX(str));
409  }
410 
411  str = sf_get_string(mFile.get(), SF_STR_COMMENT);
412  if (str) {
413  tags->SetTag(TAG_COMMENTS, UTF8CTOWX(str));
414  }
415 
416  str = sf_get_string(mFile.get(), SF_STR_DATE);
417  if (str) {
418  tags->SetTag(TAG_YEAR, UTF8CTOWX(str));
419  }
420 
421  str = sf_get_string(mFile.get(), SF_STR_COPYRIGHT);
422  if (str) {
424  }
425 
426  str = sf_get_string(mFile.get(), SF_STR_SOFTWARE);
427  if (str) {
428  tags->SetTag(TAG_SOFTWARE, UTF8CTOWX(str));
429  }
430 
431  str = sf_get_string(mFile.get(), SF_STR_TRACKNUMBER);
432  if (str) {
433  tags->SetTag(TAG_TRACK, UTF8CTOWX(str));
434  }
435 
436  str = sf_get_string(mFile.get(), SF_STR_GENRE);
437  if (str) {
438  tags->SetTag(TAG_GENRE, UTF8CTOWX(str));
439  }
440 
441 #if defined(USE_LIBID3TAG)
442  if (((mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) ||
443  ((mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)) {
444  wxFFile f(mFilename, wxT("rb"));
445  if (f.IsOpened()) {
446  char id[5];
447  wxUint32 len;
448 
449  id[4] = '\0';
450 
451  f.Seek(12); // Skip filetype, length, and formtype
452 
453  while (!f.Error()) {
454  f.Read(id, 4); // Get chunk type
455  if (f.Eof()) {
456  break;
457  }
458  f.Read(&len, 4);
459  if((mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF)
460  len = wxUINT32_SWAP_ON_LE(len);
461 
462  if (wxStricmp(id, "ID3 ") != 0) { // must be case insensitive
463  f.Seek(len + (len & 0x01), wxFromCurrent);
464  continue;
465  }
466 
467 
468  id3_tag_holder tp;
469  {
470  ArrayOf<id3_byte_t> buffer{ len };
471  if (!buffer) {
472  break;
473  }
474 
475  f.Read(buffer.get(), len);
476  tp.reset( id3_tag_parse(buffer.get(), len) );
477  }
478 
479  if (!tp) {
480  break;
481  }
482 
483  // Loop through all frames
484  bool have_year = false;
485  for (int i = 0; i < (int) tp->nframes; i++) {
486  struct id3_frame *frame = tp->frames[i];
487 
488  // wxPrintf("ID: %08x '%4s'\n", (int) *(int *)frame->id, frame->id);
489  // wxPrintf("Desc: %s\n", frame->description);
490  // wxPrintf("Num fields: %d\n", frame->nfields);
491 
492  // for (int j = 0; j < (int) frame->nfields; j++) {
493  // wxPrintf("field %d type %d\n", j, frame->fields[j].type );
494  // if (frame->fields[j].type == ID3_FIELD_TYPE_STRINGLIST) {
495  // wxPrintf("num strings %d\n", frame->fields[j].stringlist.nstrings);
496  // }
497  // }
498 
499  wxString n, v;
500 
501  // Determine the tag name
502  if (strcmp(frame->id, ID3_FRAME_TITLE) == 0) {
503  n = TAG_TITLE;
504  }
505  else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0) {
506  n = TAG_ARTIST;
507  }
508  else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0) {
509  n = TAG_ALBUM;
510  }
511  else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0) {
512  n = TAG_TRACK;
513  }
514  else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0) {
515  // LLL: When libid3tag encounters the "TYER" tag, it converts it to a
516  // "ZOBS" (obsolete) tag and adds a "TDRC" tag at the end of the
517  // list of tags using the first 4 characters of the "TYER" tag.
518  // Since we write both the "TDRC" and "TYER" tags, the "TDRC" tag
519  // will always be encountered first in the list. We want use it
520  // since the converted "TYER" tag may have been truncated.
521  if (have_year) {
522  continue;
523  }
524  n = TAG_YEAR;
525  have_year = true;
526  }
527  else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0) {
528  n = TAG_COMMENTS;
529  }
530  else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) {
531  n = TAG_GENRE;
532  }
533  else {
534  // Use frame description as default tag name. The descriptions
535  // may include several "meanings" separated by "/" characters, so
536  // we just use the first meaning
537  n = UTF8CTOWX(frame->description).BeforeFirst(wxT('/'));
538  }
539 
540  const id3_ucs4_t *ustr = NULL;
541 
542  if (n == TAG_COMMENTS) {
543  ustr = id3_field_getfullstring(&frame->fields[3]);
544  }
545  else if (frame->nfields == 3) {
546  ustr = id3_field_getstring(&frame->fields[1]);
547  if (ustr) {
548  // Is this duplication really needed?
549  MallocString<> convStr{ (char *)id3_ucs4_utf8duplicate(ustr) };
550  n = UTF8CTOWX(convStr.get());
551  }
552 
553  ustr = id3_field_getstring(&frame->fields[2]);
554  }
555  else if (frame->nfields >= 2) {
556  ustr = id3_field_getstrings(&frame->fields[1], 0);
557  }
558 
559  if (ustr) {
560  // Is this duplication really needed?
561  MallocString<> convStr{ (char *)id3_ucs4_utf8duplicate(ustr) };
562  v = UTF8CTOWX(convStr.get());
563  }
564 
565  if (!n.empty() && !v.empty()) {
566  tags->SetTag(n, v);
567  }
568  }
569 
570  // Convert v1 genre to name
571  if (tags->HasTag(TAG_GENRE)) {
572  long g = -1;
573  if (tags->GetTag(TAG_GENRE).ToLong(&g)) {
574  tags->SetTag(TAG_GENRE, tags->GetGenre(g));
575  }
576  }
577 
578  break;
579  }
580  }
581  }
582 #endif
583 
584  return updateResult;
585 }
586 
588 {
589 }
PCMImportFileHandle::mInfo
const SF_INFO mInfo
Definition: ImportPCM.cpp:110
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
SampleBuffer::Allocate
SampleBuffer & Allocate(size_t count, sampleFormat format)
Definition: SampleFormat.h:84
TrackHolders
std::vector< std::vector< std::shared_ptr< WaveTrack > > > TrackHolders
Definition: Import.h:39
BasicUI::ProgressResult::Success
@ Success
registered
static Importer::RegisteredImportPlugin registered
Definition: ImportPCM.cpp:184
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: TranslatableString.h:295
ImportPlugin
Base class for FlacImportPlugin, LOFImportPlugin, MP3ImportPlugin, OggImportPlugin and PCMImportPlugi...
Definition: ImportPlugin.h:67
str
#define str(a)
Definition: DBConnection.cpp:30
Import.h
Tags::HasTag
bool HasTag(const wxString &name) const
Definition: Tags.cpp:452
Tags
ID3 Tags (for MP3)
Definition: Tags.h:74
PCMImportFileHandle::GetStreamInfo
const TranslatableStrings & GetStreamInfo() override
Definition: ImportPCM.cpp:99
TAG_TRACK
#define TAG_TRACK
Definition: Tags.h:63
BasicUI::ProgressResult
ProgressResult
Definition: BasicUI.h:145
sf_header_name
wxString sf_header_name(int format)
Get the string name of the specified container format.
Definition: FileFormats.cpp:111
SAMPLE_SIZE
#define SAMPLE_SIZE(SampleFormat)
Definition: SampleFormat.h:44
RefreshCode::Cancelled
@ Cancelled
Definition: RefreshCode.h:23
MallocString
std::unique_ptr< Character[], freer > MallocString
Definition: MemoryX.h:274
XO
#define XO(s)
Definition: Internat.h:31
PCMImportFileHandle::GetStreamCount
wxInt32 GetStreamCount() override
Definition: ImportPCM.cpp:97
PCMImportFileHandle::~PCMImportFileHandle
~PCMImportFileHandle()
Definition: ImportPCM.cpp:587
PCMImportFileHandle::SetStreamUsage
void SetStreamUsage(wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
Definition: ImportPCM.cpp:105
PCMImportFileHandle::mFile
SFFile mFile
Definition: ImportPCM.cpp:109
TAG_SOFTWARE
#define TAG_SOFTWARE
Definition: Tags.h:67
PCMImportFileHandle::PCMImportFileHandle
PCMImportFileHandle(const FilePath &name, SFFile &&file, SF_INFO info)
Definition: ImportPCM.cpp:188
Tags::GetTag
wxString GetTag(const wxString &name) const
Definition: Tags.cpp:461
ImportFileHandle::mProgress
std::unique_ptr< ProgressDialog > mProgress
Definition: ImportPlugin.h:159
floatSample
@ floatSample
Definition: SampleFormat.h:34
Tags::GetGenre
wxString GetGenre(int value)
Definition: Tags.cpp:428
ImportFileHandle::CreateProgress
void CreateProgress()
Definition: ImportPlugin.cpp:45
ImportFileHandle::NewWaveTrack
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.
Definition: ImportPlugin.cpp:69
FilePath
wxString FilePath
Definition: Project.h:20
Tags::SetTag
void SetTag(const wxString &name, const wxString &value, const bool bSpecialTag=false)
Definition: Tags.cpp:486
ImportFileHandle::ChooseFormat
static sampleFormat ChooseFormat(sampleFormat effectiveFormat)
Choose appropriate format, which will not be narrower than the specified one.
Definition: ImportPlugin.cpp:54
int16Sample
@ int16Sample
Definition: SampleFormat.h:32
sf_subtype_to_effective_format
sampleFormat sf_subtype_to_effective_format(unsigned int format)
Choose the narrowest value in the sampleFormat enumeration for a given libsndfile format.
Definition: FileFormats.cpp:229
name
const TranslatableString name
Definition: Distortion.cpp:98
UTF8CTOWX
#define UTF8CTOWX(X)
Definition: Internat.h:159
TAG_GENRE
#define TAG_GENRE
Definition: Tags.h:65
PCMImportPlugin::GetPluginStringID
wxString GetPluginStringID() override
Definition: ImportPCM.cpp:79
ImportFileHandle::mFilename
FilePath mFilename
Definition: ImportPlugin.h:158
TAG_YEAR
#define TAG_YEAR
Definition: Tags.h:64
SFFile
Definition: FileFormats.h:143
TAG_COPYRIGHT
#define TAG_COPYRIGHT
Definition: Tags.h:68
ImportFileHandle
An ImportFileHandle for data.
Definition: ImportPlugin.h:107
DESC
#define DESC
Definition: ImportPCM.cpp:67
WaveTrackFactory
Used to create or clone a WaveTrack, with appropriate context from the project that will own the trac...
Definition: WaveTrack.h:713
SampleBuffer
Definition: SampleFormat.h:69
sampleFormat
sampleFormat
Definition: SampleFormat.h:29
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
PCMImportFileHandle::mFormat
sampleFormat mFormat
Definition: ImportPCM.cpp:111
PCMImportPlugin::PCMImportPlugin
PCMImportPlugin()
Definition: ImportPCM.cpp:72
PCMImportPlugin::~PCMImportPlugin
~PCMImportPlugin()
Definition: ImportPCM.cpp:77
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
PCMImportPlugin::GetPluginFormatDescription
TranslatableString GetPluginFormatDescription() override
Definition: ImportPCM.cpp:114
ImportPlugin.h
The interface that all file import "plugins" (if you want to call them that) must implement....
Importer::RegisteredImportPlugin
Definition: Import.h:85
TAG_COMMENTS
#define TAG_COMMENTS
Definition: Tags.h:66
PCMImportFileHandle::Import
ProgressResult Import(WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override
Definition: ImportPCM.cpp:288
TAG_ARTIST
#define TAG_ARTIST
Definition: Tags.h:61
Prefs.h
PCMImportPlugin::Open
std::unique_ptr< ImportFileHandle > Open(const FilePath &Filename, AudacityProject *) override
Definition: ImportPCM.cpp:119
sf_get_all_extensions
FileExtensions sf_get_all_extensions()
Definition: FileFormats.cpp:241
PCMImportFileHandle
An ImportFileHandle for PCM data.
Definition: ImportPCM.cpp:87
NewChannelGroup
std::vector< std::shared_ptr< WaveTrack > > NewChannelGroup
Definition: Import.cpp:62
ImportFileHandle::ByteCount
unsigned long long ByteCount
Definition: ImportPlugin.h:127
PCMImportFileHandle::GetFileUncompressedBytes
ByteCount GetFileUncompressedBytes() override
Definition: ImportPCM.cpp:274
PCMImportPlugin
An ImportPlugin for PCM data.
Definition: ImportPCM.cpp:70
ArrayOf
Memory.h template class for making an array of float, bool, etc.
Definition: MemoryX.h:27
TAG_TITLE
#define TAG_TITLE
Definition: Tags.h:60
PCMImportFileHandle::GetFileDescription
TranslatableString GetFileDescription() override
Definition: ImportPCM.cpp:208
SampleBuffer::ptr
samplePtr ptr() const
Definition: SampleFormat.h:98
TAG_ALBUM
#define TAG_ALBUM
Definition: Tags.h:62