1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-01 16:19:43 +02:00
audacity/src/FileFormats.cpp
Paul Licameli 4d09705a73 Change XO to XXO in many more places, with no effects at all...
... because the two macros have the same expansion, and are both checked for
in the --keyword arguments passed to msgfmt by locale/update_po_files.sh.

This commit makes ONLY such changes, and comments in Internat.h.  It is big
but quite harmless.

The intention is to introduce a type distinction in a later release, by defining
XXO differently.  XXO is used where & characters in strings (for hotkeys of menu
items or control prompts) are permitted, XO where not.
2020-05-22 13:07:50 -04:00

365 lines
8.2 KiB
C++

/**********************************************************************
Audacity: A Digital Audio Editor
FileFormats.cpp
Dominic Mazzoni
*******************************************************************//*!
\file FileFormats.cpp
\brief Works with libsndfile to provide encoding and other file
information.
*//*******************************************************************/
#include "Audacity.h"
#include "FileFormats.h"
#include <wx/arrstr.h>
#include <wx/intl.h>
#include "sndfile.h"
#include "Internat.h"
#include "widgets/AudacityMessageBox.h"
#include "Prefs.h"
#ifndef SNDFILE_1
#error Requires libsndfile 1.0 or higher
#endif
//
// enumerating headers
//
int sf_num_headers()
{
int count;
sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT,
&count, sizeof(count));
return count;
}
wxString sf_header_index_name(int format)
{
SF_FORMAT_INFO format_info;
memset(&format_info, 0, sizeof(format_info));
format_info.format = format;
sf_command(NULL, SFC_GET_FORMAT_MAJOR,
&format_info, sizeof (format_info)) ;
return LAT1CTOWX(format_info.name);
}
unsigned int sf_header_index_to_type(int i)
{
SF_FORMAT_INFO format_info ;
memset(&format_info, 0, sizeof(format_info));
format_info.format = i;
sf_command (NULL, SFC_GET_FORMAT_MAJOR,
&format_info, sizeof (format_info));
return format_info.format & SF_FORMAT_TYPEMASK;
}
//
// enumerating encodings
//
int sf_num_encodings()
{
int count ;
sf_command (NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int)) ;
return count;
}
wxString sf_encoding_index_name(int i)
{
SF_FORMAT_INFO format_info ;
memset(&format_info, 0, sizeof(format_info));
format_info.format = i;
sf_command (NULL, SFC_GET_FORMAT_SUBTYPE,
&format_info, sizeof (format_info));
return sf_normalize_name(format_info.name);
}
unsigned int sf_encoding_index_to_subtype(int i)
{
SF_FORMAT_INFO format_info ;
memset(&format_info, 0, sizeof(format_info));
format_info.format = i;
sf_command (NULL, SFC_GET_FORMAT_SUBTYPE,
&format_info, sizeof (format_info));
return format_info.format & SF_FORMAT_SUBMASK;
}
//
// getting info about an actual SF format
//
wxString sf_header_name(int format)
{
SF_FORMAT_INFO format_info;
memset(&format_info, 0, sizeof(format_info));
format_info.format = (format & SF_FORMAT_TYPEMASK);
sf_command(NULL, SFC_GET_FORMAT_INFO, &format_info, sizeof(format_info));
return LAT1CTOWX(format_info.name);
}
wxString sf_header_shortname(int format)
{
SF_FORMAT_INFO format_info;
int i;
wxString s;
memset(&format_info, 0, sizeof(format_info));
format_info.format = (format & SF_FORMAT_TYPEMASK);
sf_command(NULL, SFC_GET_FORMAT_INFO, &format_info, sizeof(format_info));
MallocString<> tmp { strdup( format_info.name ) };
i = 0;
while(tmp[i]) {
if (tmp[i]==' ')
tmp[i] = 0;
else
i++;
}
s = LAT1CTOWX(tmp.get());
return s;
}
wxString sf_header_extension(int format)
{
SF_FORMAT_INFO format_info;
memset(&format_info, 0, sizeof(format_info));
format_info.format = (format & SF_FORMAT_TYPEMASK);
sf_command(NULL, SFC_GET_FORMAT_INFO, &format_info, sizeof(format_info));
return LAT1CTOWX(format_info.extension);
}
wxString sf_encoding_name(int encoding)
{
SF_FORMAT_INFO format_info;
memset(&format_info, 0, sizeof(format_info));
format_info.format = (encoding & SF_FORMAT_SUBMASK);
sf_command(NULL, SFC_GET_FORMAT_INFO, &format_info, sizeof(format_info));
return sf_normalize_name(format_info.name);
}
int sf_num_simple_formats()
{
int count ;
sf_command (NULL, SFC_GET_SIMPLE_FORMAT_COUNT, &count, sizeof (int)) ;
return count;
}
static SF_FORMAT_INFO g_format_info;
SF_FORMAT_INFO *sf_simple_format(int i)
{
memset(&g_format_info, 0, sizeof(g_format_info));
g_format_info.format = i;
sf_command (NULL, SFC_GET_SIMPLE_FORMAT,
&g_format_info, sizeof(g_format_info));
return &g_format_info;
}
bool sf_subtype_more_than_16_bits(unsigned int format)
{
unsigned int subtype = format & SF_FORMAT_SUBMASK;
return (subtype == SF_FORMAT_FLOAT ||
subtype == SF_FORMAT_DOUBLE ||
subtype == SF_FORMAT_PCM_24 ||
subtype == SF_FORMAT_PCM_32);
}
bool sf_subtype_is_integer(unsigned int format)
{
unsigned int subtype = format & SF_FORMAT_SUBMASK;
return (subtype == SF_FORMAT_PCM_16 ||
subtype == SF_FORMAT_PCM_24 ||
subtype == SF_FORMAT_PCM_32);
}
int sf_subtype_bytes_per_sample(unsigned int format){
unsigned int subtype = format & SF_FORMAT_SUBMASK;
if( subtype == SF_FORMAT_PCM_S8 )
return 1;
if( subtype == SF_FORMAT_PCM_U8 )
return 1;
if( subtype == SF_FORMAT_PCM_16 )
return 2;
if( subtype == SF_FORMAT_PCM_24 )
return 3;
if( subtype == SF_FORMAT_PCM_32 )
return 4;
if( subtype == SF_FORMAT_FLOAT )
return 4;
if( subtype == SF_FORMAT_DOUBLE )
return 8;
// might be different to 2, but this is good enough for
// WAV and AIFF file size error trapping.
return 2;
}
FileExtensions sf_get_all_extensions()
{
FileExtensions exts;
SF_FORMAT_INFO format_info;
int count, k;
memset(&format_info, 0, sizeof(format_info));
sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT,
&count, sizeof(count));
for(k=0; k<count; k++) {
format_info.format = k;
sf_command(NULL, SFC_GET_FORMAT_MAJOR,
&format_info, sizeof (format_info)) ;
exts.push_back(LAT1CTOWX(format_info.extension));
}
// Some other extensions that are often sound files
// but aren't included by libsndfile
exts.insert( exts.end(), {
wxT("aif") , // AIFF file with a DOS-style extension
wxT("ircam") ,
wxT("snd") ,
wxT("svx") ,
wxT("svx8") ,
wxT("sv16") ,
} );
return exts;
}
wxString sf_normalize_name(const char *name)
{
wxString n = LAT1CTOWX(name);
n.Replace(wxT("8 bit"), wxT("8-bit"));
n.Replace(wxT("16 bit"), wxT("16-bit"));
n.Replace(wxT("24 bit"), wxT("24-bit"));
n.Replace(wxT("32 bit"), wxT("32-bit"));
n.Replace(wxT("64 bit"), wxT("64-bit"));
return n;
}
#ifdef __WXMAC__
// TODO: find out the appropriate OSType
// for the ones with an '????'. The others
// are at least the same type used by
// SoundApp.
#define NUM_HEADERS 13
//
// Mac OS 4-char type
//
# ifdef __UNIX__
# include <CoreServices/CoreServices.h>
# else
# include <Types.h>
# endif
OSType MacNames[NUM_HEADERS] = {
'WAVE', // WAVE
'AIFF', // AIFF
'NeXT', // Sun/NeXT AU
'BINA', // RAW i.e. binary
'PAR ', // ??? Ensoniq PARIS
'8SVX', // Amiga IFF / SVX8
'NIST', // ??? NIST/Sphere
'VOC ', // VOC
'\?\?\?\?', // ?? Propellorheads Rex
'SF ', // ?? IRCAM
'W64 ', // ?? Wave64
'MAT4', // ?? Matlab 4
'MAT5', // ?? Matlab 5
};
static OSType sf_header_mactype(int format)
{
if (format >= 0x10000)
return MacNames[(format/0x10000)-1];
else if (format>=0 && format<NUM_HEADERS)
return MacNames[format];
else
return '\?\?\?\?';
}
#endif // __WXMAC__
ODLock libSndFileMutex;
int SFFileCloser::operator() (SNDFILE *sf) const
{
auto err = SFCall<int>(sf_close, sf);
if (err) {
char buffer[1000];
sf_error_str(sf, buffer, 1000);
AudacityMessageBox(
/* i18n-hint: %s will be the error message from the libsndfile software library */
XO( "Error (file may not have been written): %s" )
// Not attempting to localize error messages
// from the library
.Format( buffer ));
}
return err;
}
ChoiceSetting FileFormatsCopyOrEditSetting{
wxT("/FileFormats/CopyOrEditUncompressedData"),
{
EnumValueSymbol{
wxT("copy"),
XXO("&Copy uncompressed files into the project (safer)")
},
EnumValueSymbol{
wxT("edit"),
XXO("&Read uncompressed files from original location (faster)")
},
},
0 // copy
};
ChoiceSetting FileFormatsSaveWithDependenciesSetting{
wxT("/FileFormats/SaveProjectWithDependencies"),
{
{ wxT("copy"), XXO("&Copy all audio into project (safest)") },
{ wxT("never"), XXO("Do &not copy any audio") },
{ wxT("ask"), XXO("As&k") },
},
2 // ask
};