Audacity 3.2.0
Public Member Functions | Private Member Functions | List of all members
ExportOGG Class Referencefinal
Inheritance diagram for ExportOGG:
[legend]
Collaboration diagram for ExportOGG:
[legend]

Public Member Functions

 ExportOGG ()
 
void OptionsCreate (ShuttleGui &S, int format) override
 
ProgressResult Export (AudacityProject *project, std::unique_ptr< BasicUI::ProgressDialog > &pDialog, unsigned channels, const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, MixerSpec *mixerSpec=NULL, const Tags *metadata=NULL, int subformat=0) override
 called to export audio into a file. More...
 
- Public Member Functions inherited from ExportPlugin
 ExportPlugin ()
 
virtual ~ExportPlugin ()
 
int AddFormat ()
 Add a NEW entry to the list of formats this plug-in can export. More...
 
void SetFormat (const wxString &format, int index)
 
void SetDescription (const TranslatableString &description, int index)
 
void AddExtension (const FileExtension &extension, int index)
 
void SetExtensions (FileExtensions extensions, int index)
 
void SetMask (FileNames::FileTypes mask, int index)
 
void SetMaxChannels (unsigned maxchannels, unsigned index)
 
void SetCanMetaData (bool canmetadata, int index)
 
virtual int GetFormatCount ()
 
virtual wxString GetFormat (int index)
 
TranslatableString GetDescription (int index)
 
virtual FileExtension GetExtension (int index=0)
 Return the (first) file name extension for the sub-format. More...
 
virtual FileExtensions GetExtensions (int index=0)
 Return all the file name extensions used for the sub-format. More...
 
FileNames::FileTypes GetMask (int index)
 
virtual unsigned GetMaxChannels (int index)
 
virtual bool GetCanMetaData (int index)
 
virtual bool IsExtension (const FileExtension &ext, int index)
 
virtual bool DisplayOptions (wxWindow *parent, int format=0)
 
virtual void OptionsCreate (ShuttleGui &S, int format)=0
 
virtual bool CheckFileName (wxFileName &filename, int format=0)
 
virtual int SetNumExportChannels ()
 Exporter plug-ins may override this to specify the number of channels in exported file. -1 for unspecified. More...
 
virtual ProgressResult Export (AudacityProject *project, std::unique_ptr< BasicUI::ProgressDialog > &pDialog, unsigned channels, const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, MixerSpec *mixerSpec=NULL, const Tags *metadata=NULL, int subformat=0)=0
 called to export audio into a file. More...
 

Private Member Functions

bool FillComment (AudacityProject *project, vorbis_comment *comment, const Tags *metadata)
 

Additional Inherited Members

- Public Types inherited from ExportPlugin
using ProgressResult = BasicUI::ProgressResult
 
- Protected Member Functions inherited from ExportPlugin
std::unique_ptr< MixerCreateMixer (const TrackList &tracks, bool selectionOnly, double startTime, double stopTime, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, double outRate, sampleFormat outFormat, MixerSpec *mixerSpec)
 
- Static Protected Member Functions inherited from ExportPlugin
static void InitProgress (std::unique_ptr< BasicUI::ProgressDialog > &pDialog, const TranslatableString &title, const TranslatableString &message)
 
static void InitProgress (std::unique_ptr< BasicUI::ProgressDialog > &pDialog, const wxFileNameWrapper &title, const TranslatableString &message)
 

Detailed Description

Definition at line 123 of file ExportOGG.cpp.

Constructor & Destructor Documentation

◆ ExportOGG()

ExportOGG::ExportOGG ( )

Definition at line 148 of file ExportOGG.cpp.

149: ExportPlugin()
150{
151 AddFormat();
152 SetFormat(wxT("OGG"),0);
153 AddExtension(wxT("ogg"),0);
154 SetMaxChannels(255,0);
155 SetCanMetaData(true,0);
156 SetDescription(XO("Ogg Vorbis Files"),0);
157}
wxT("CloseDown"))
XO("Cut/Copy/Paste")
ExportPlugin()
Definition: Export.cpp:80
void AddExtension(const FileExtension &extension, int index)
Definition: Export.cpp:126
int AddFormat()
Add a NEW entry to the list of formats this plug-in can export.
Definition: Export.cpp:100
void SetFormat(const wxString &format, int index)
Definition: Export.cpp:116
void SetDescription(const TranslatableString &description, int index)
Definition: Export.cpp:121
void SetCanMetaData(bool canmetadata, int index)
Definition: Export.cpp:146
void SetMaxChannels(unsigned maxchannels, unsigned index)
Definition: Export.cpp:141

References ExportPlugin::AddExtension(), ExportPlugin::AddFormat(), ExportPlugin::SetCanMetaData(), ExportPlugin::SetDescription(), ExportPlugin::SetFormat(), ExportPlugin::SetMaxChannels(), wxT(), and XO().

Here is the call graph for this function:

Member Function Documentation

◆ Export()

ProgressResult ExportOGG::Export ( AudacityProject project,
std::unique_ptr< BasicUI::ProgressDialog > &  pDialog,
unsigned  channels,
const wxFileNameWrapper fName,
bool  selectedOnly,
double  t0,
double  t1,
MixerSpec mixerSpec = NULL,
const Tags metadata = NULL,
int  subformat = 0 
)
overridevirtual

called to export audio into a file.

Parameters
pDialogTo be initialized with pointer to a NEW ProgressDialog if it was null, otherwise gives an existing dialog to be reused (working around a problem in wxWidgets for Mac; see bug 1600)
selectedOnlySet to true if all tracks should be mixed, to false if only the selected tracks should be mixed and exported.
metadataA Tags object that will over-ride the one in *project and be used to tag the file that is exported.
subformatControl which of the multiple formats this exporter is capable of exporting should be used. Used where a single export plug-in handles a number of related formats, but they have separate entries in the Format drop-down list box. For example, the options to export to "Other PCM", "AIFF 16 Bit" and "WAV 16 Bit" are all the same libsndfile export plug-in, but with subformat set to 0, 1, and 2 respectively.
Returns
ProgressResult::Failed or ProgressResult::Cancelled if export fails to complete for any reason, in which case this function is responsible for alerting the user. Otherwise ProgressResult::Success or ProgressResult::Stopped

Implements ExportPlugin.

Definition at line 159 of file ExportOGG.cpp.

169{
170 double rate = ProjectRate::Get( *project ).GetRate();
171 const auto &tracks = TrackList::Get( *project );
172 double quality = (gPrefs->Read(wxT("/FileFormats/OggExportQuality"), 50)/(float)100.0);
173
174 wxLogNull logNo; // temporarily disable wxWidgets error messages
175 auto updateResult = ProgressResult::Success;
176 int eos = 0;
177
178 FileIO outFile(fName, FileIO::Output);
179
180 if (!outFile.IsOpened()) {
181 AudacityMessageBox( XO("Unable to open target file for writing") );
183 }
184
185 // All the Ogg and Vorbis encoding data
186 ogg_stream_state stream;
187 ogg_page page;
188 ogg_packet packet;
189
190 vorbis_info info;
191 vorbis_comment comment;
192 vorbis_dsp_state dsp;
193 vorbis_block block;
194
195
196 auto cleanup1 = finally( [&] {
197 vorbis_info_clear(&info);
198 } );
199
200
201 // Many of the library functions called below return 0 for success and
202 // various nonzero codes for failure.
203
204 // Encoding setup
205 vorbis_info_init(&info);
206 if (vorbis_encode_init_vbr(&info, numChannels, (int)(rate + 0.5), quality)) {
207 // TODO: more precise message
208 AudacityMessageBox( XO("Unable to export - rate or quality problem") );
210 }
211
212 auto cleanup2 = finally( [&] {
213 ogg_stream_clear(&stream);
214
215 vorbis_block_clear(&block);
216 vorbis_dsp_clear(&dsp);
217 vorbis_comment_clear(&comment);
218 } );
219
220 // Retrieve tags
221 if (!FillComment(project, &comment, metadata)) {
222 AudacityMessageBox( XO("Unable to export - problem with metadata") );
224 }
225
226 // Set up analysis state and auxiliary encoding storage
227 if (vorbis_analysis_init(&dsp, &info) ||
228 vorbis_block_init(&dsp, &block)) {
229 AudacityMessageBox( XO("Unable to export - problem initialising") );
231 }
232
233 // Set up packet->stream encoder. According to encoder example,
234 // a random serial number makes it more likely that you can make
235 // chained streams with concatenation.
236 srand(time(NULL));
237 if (ogg_stream_init(&stream, rand())) {
238 AudacityMessageBox( XO("Unable to export - problem creating stream") );
240 }
241
242 // First we need to write the required headers:
243 // 1. The Ogg bitstream header, which contains codec setup params
244 // 2. The Vorbis comment header
245 // 3. The bitstream codebook.
246 //
247 // After we create those our responsibility is complete, libvorbis will
248 // take care of any other ogg bitstream constraints (again, according
249 // to the example encoder source)
250 ogg_packet bitstream_header;
251 ogg_packet comment_header;
252 ogg_packet codebook_header;
253
254 if(vorbis_analysis_headerout(&dsp, &comment, &bitstream_header, &comment_header,
255 &codebook_header) ||
256 // Place these headers into the stream
257 ogg_stream_packetin(&stream, &bitstream_header) ||
258 ogg_stream_packetin(&stream, &comment_header) ||
259 ogg_stream_packetin(&stream, &codebook_header)) {
260 AudacityMessageBox( XO("Unable to export - problem with packets") );
262 }
263
264 // Flushing these headers now guarantees that audio data will
265 // start on a NEW page, which apparently makes streaming easier
266 while (ogg_stream_flush(&stream, &page)) {
267 if ( outFile.Write(page.header, page.header_len).GetLastError() ||
268 outFile.Write(page.body, page.body_len).GetLastError()) {
269 AudacityMessageBox( XO("Unable to export - problem with file") );
271 }
272 }
273
274 {
275 auto mixer = CreateMixer(tracks, selectionOnly,
276 t0, t1,
277 numChannels, SAMPLES_PER_RUN, false,
278 rate, floatSample, mixerSpec);
279
280 InitProgress( pDialog, fName,
281 selectionOnly
282 ? XO("Exporting the selected audio as Ogg Vorbis")
283 : XO("Exporting the audio as Ogg Vorbis") );
284 auto &progress = *pDialog;
285
286 while (updateResult == ProgressResult::Success && !eos) {
287 float **vorbis_buffer = vorbis_analysis_buffer(&dsp, SAMPLES_PER_RUN);
288 auto samplesThisRun = mixer->Process();
289 int err;
290 if (samplesThisRun == 0) {
291 // Tell the library that we wrote 0 bytes - signalling the end.
292 err = vorbis_analysis_wrote(&dsp, 0);
293 }
294 else {
295
296 for (size_t i = 0; i < numChannels; i++) {
297 float *temp = (float *)mixer->GetBuffer(i);
298 memcpy(vorbis_buffer[i], temp, sizeof(float)*SAMPLES_PER_RUN);
299 }
300
301 // tell the encoder how many samples we have
302 err = vorbis_analysis_wrote(&dsp, samplesThisRun);
303 }
304
305 // I don't understand what this call does, so here is the comment
306 // from the example, verbatim:
307 //
308 // vorbis does some data preanalysis, then divvies up blocks
309 // for more involved (potentially parallel) processing. Get
310 // a single block for encoding now
311 while (!err && vorbis_analysis_blockout(&dsp, &block) == 1) {
312
313 // analysis, assume we want to use bitrate management
314 err = vorbis_analysis(&block, NULL);
315 if (!err)
316 err = vorbis_bitrate_addblock(&block);
317
318 while (!err && vorbis_bitrate_flushpacket(&dsp, &packet)) {
319
320 // add the packet to the bitstream
321 err = ogg_stream_packetin(&stream, &packet);
322
323 // From vorbis-tools-1.0/oggenc/encode.c:
324 // If we've gone over a page boundary, we can do actual output,
325 // so do so (for however many pages are available).
326
327 while (!err && !eos) {
328 int result = ogg_stream_pageout(&stream, &page);
329 if (!result) {
330 break;
331 }
332
333 if ( outFile.Write(page.header, page.header_len).GetLastError() ||
334 outFile.Write(page.body, page.body_len).GetLastError()) {
335 // TODO: more precise message
338 }
339
340 if (ogg_page_eos(&page)) {
341 eos = 1;
342 }
343 }
344 }
345 }
346
347 if (err) {
348 updateResult = ProgressResult::Cancelled;
349 // TODO: more precise message
350 ShowExportErrorDialog("OGG:355");
351 break;
352 }
353
354 updateResult = progress.Poll(mixer->MixGetCurrentTime() - t0, t1 - t0);
355 }
356 }
357
358 if ( !outFile.Close() ) {
359 updateResult = ProgressResult::Cancelled;
360 // TODO: more precise message
361 ShowExportErrorDialog("OGG:366");
362 }
363
364 return updateResult;
365}
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
void ShowExportErrorDialog(wxString ErrorCode, TranslatableString message, const TranslatableString &caption, bool allowReporting)
Definition: Export.cpp:1503
void ShowDiskFullExportErrorDialog(const wxFileNameWrapper &fileName)
Definition: Export.cpp:1516
#define SAMPLES_PER_RUN
Definition: ExportOGG.cpp:121
FileConfig * gPrefs
Definition: Prefs.cpp:70
bool FillComment(AudacityProject *project, vorbis_comment *comment, const Tags *metadata)
Definition: ExportOGG.cpp:372
static void InitProgress(std::unique_ptr< BasicUI::ProgressDialog > &pDialog, const TranslatableString &title, const TranslatableString &message)
Definition: Export.cpp:250
std::unique_ptr< Mixer > CreateMixer(const TrackList &tracks, bool selectionOnly, double startTime, double stopTime, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, double outRate, sampleFormat outFormat, MixerSpec *mixerSpec)
Definition: Export.cpp:222
Definition: FileIO.h:22
@ Output
Definition: FileIO.h:27
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
double GetRate() const
Definition: ProjectRate.cpp:53
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:385

References AudacityMessageBox(), RefreshCode::Cancelled, FileIO::Close(), ExportPlugin::CreateMixer(), FillComment(), floatSample, ProjectRate::Get(), TrackList::Get(), ProjectRate::GetRate(), gPrefs, ExportPlugin::InitProgress(), FileIO::IsOpened(), FileIO::Output, SAMPLES_PER_RUN, ShowDiskFullExportErrorDialog(), ShowExportErrorDialog(), BasicUI::Success, FileIO::Write(), wxT(), and XO().

Here is the call graph for this function:

◆ FillComment()

bool ExportOGG::FillComment ( AudacityProject project,
vorbis_comment *  comment,
const Tags metadata 
)
private

Definition at line 372 of file ExportOGG.cpp.

373{
374 // Retrieve tags from project if not over-ridden
375 if (metadata == NULL)
376 metadata = &Tags::Get( *project );
377
378 vorbis_comment_init(comment);
379
380 wxString n;
381 for (const auto &pair : metadata->GetRange()) {
382 n = pair.first;
383 const auto &v = pair.second;
384 if (n == TAG_YEAR) {
385 n = wxT("DATE");
386 }
387 vorbis_comment_add_tag(comment,
388 (char *) (const char *) n.mb_str(wxConvUTF8),
389 (char *) (const char *) v.mb_str(wxConvUTF8));
390 }
391
392 return true;
393}
#define TAG_YEAR
Definition: Tags.h:62
Iterators GetRange() const
Definition: Tags.cpp:436
static Tags & Get(AudacityProject &project)
Definition: Tags.cpp:214

References Tags::Get(), Tags::GetRange(), TAG_YEAR, and wxT().

Referenced by Export().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OptionsCreate()

void ExportOGG::OptionsCreate ( ShuttleGui S,
int  format 
)
overridevirtual

Implements ExportPlugin.

Definition at line 367 of file ExportOGG.cpp.

368{
369 S.AddWindow( safenew ExportOGGOptions{ S.GetParent(), format } );
370}
int format
Definition: ExportPCM.cpp:53
#define safenew
Definition: MemoryX.h:10
#define S(N)
Definition: ToChars.cpp:64

References format, S, and safenew.


The documentation for this class was generated from the following file: