31#include <opus/opusfile.h>
33#define DESC XO("Opus files")
35static const auto exts = { L
"opus", L
"ogg" };
45 std::unique_ptr<ImportFileHandle>
Open(
62 std::optional<LibFileFormats::AcidizerTags>& outAcidTags)
override;
111 return wxT(
"libopus");
121 auto handle = std::make_unique<OpusImportFileHandle>(filename);
123 if (!handle->IsOpen())
126 return std::move(handle);
130 std::make_unique< OpusImportPlugin >()
141 if (!
mFile.Open(filename, wxFile::read))
144 OpusFileCallbacks callbacks = {
152 mOpusFile = op_open_callbacks(
this, &callbacks,
nullptr, 0, &error);
177 std::optional<LibFileFormats::AcidizerTags>&)
190 const size_t SAMPLES_TO_READ = track->GetMaxBlockSize();
191 uint64_t totalSamplesRead = 0;
197 uint64_t samplesRead = 0;
201 int linkIndex { -1 };
202 auto samplesPerChannelRead = op_read_float(
mOpusFile, floatBuffer.get(), SAMPLES_TO_READ, &linkIndex);
204 if (samplesPerChannelRead < 0 && samplesPerChannelRead != OP_HOLE)
210 auto linkChannels = op_head(
mOpusFile, linkIndex)->channel_count;
214 NotifyImportFailed(progressListener,
XO(
"File has changed the number of channels in the middle."));
221 channel.AppendBuffer(
228 samplesRead = samplesPerChannelRead;
229 totalSamplesRead += samplesRead;
251 if (opusTags !=
nullptr)
253 for (
int i = 0; i < opusTags->comments; ++i)
255 const auto comment = opusTags->user_comments[i];
256 const auto commentLength = opusTags->comment_lengths[i];
258 std::string_view tag { comment,
259 std::string_view::size_type(commentLength) };
261 const auto separator = tag.find(
'=');
273 if (value.length() == 4 && value.ToLong(&val))
303 void* pstream,
unsigned char* ptr,
int nbytes)
307 if (!stream->mFile.IsOpened())
312 return int(stream->mFile.Read(ptr, nbytes));
316 void* pstream, opus_int64 offset,
int whence)
320 if (!stream->mFile.IsOpened())
323 wxSeekMode wxWhence = whence == SEEK_SET ? wxFromStart :
324 whence == SEEK_CUR ? wxFromCurrent :
325 whence == SEEK_END ? wxFromEnd : wxFromStart;
327 return stream->
mFile.Seek(offset, wxWhence) != wxInvalidOffset ? 0 : -1;
334 return static_cast<opus_int64
>(stream->mFile.Tell());
341 if (stream->mFile.IsOpened())
342 return stream->
mFile.Close() ? 0 : EOF;
352 return XO(
"IO error reading from file");
354 return XO(
"internal error");
356 return XO(
"not implemented");
358 return XO(
"invalid argument");
360 return XO(
"not an Opus file");
362 return XO(
"invalid header");
364 return XO(
"unsupported version");
366 return XO(
"invalid packet");
368 return XO(
"invalid stream structure");
370 return XO(
"stream is not seekable");
371 case OP_EBADTIMESTAMP:
372 return XO(
"invalid timestamp");
383 if (error == OP_ENOTFORMAT)
399 XO(
"Failed to decode Opus file: %s").
Format(error));
Declare functions to perform UTF-8 to std::wstring conversions.
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::vector< TranslatableString > TranslatableStrings
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
bool IsStopped() const noexcept
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 void ShowMessageBox(const TranslatableString &message, const TranslatableString &caption=XO("Import Project"))
static std::shared_ptr< WaveTrack > NewWaveTrack(WaveTrackFactory &trackFactory, unsigned nChannels, sampleFormat effectiveFormat, double rate)
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.
static opus_int64 OpusTellCallback(void *stream)
const sampleFormat mFormat
static TranslatableString GetOpusErrorString(int error)
wxInt32 GetStreamCount() override
void LogOpusError(const char *method, int error)
static int OpusCloseCallback(void *stream)
void SetStreamUsage(wxInt32 StreamID, bool Use) override
ByteCount GetFileUncompressedBytes() override
OpusFileCallbacks mCallbacks
static int OpusReadCallback(void *stream, unsigned char *ptr, int nbytes)
const TranslatableStrings & GetStreamInfo() override
static int OpusSeekCallback(void *stream, opus_int64 offset, int whence)
void Import(ImportProgressListener &progressListener, WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags, std::optional< LibFileFormats::AcidizerTags > &outAcidTags) override
OpusImportFileHandle(const FilePath &filename)
void NotifyImportFailed(ImportProgressListener &progressListener, int error)
TranslatableString GetFileDescription() override
std::unique_ptr< ImportFileHandle > Open(const FilePath &Filename, AudacityProject *) override
wxString GetPluginStringID() override
TranslatableString GetPluginFormatDescription() 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.
constexpr size_t npos(-1)
wxString ToWXString(const std::string &str)
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept