mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-11 17:41:15 +02:00
This commit is contained in:
parent
e2f272890c
commit
714049ffce
@ -114,9 +114,7 @@ BEGIN_EVENT_TABLE(ExportPCMOptions, wxDialog)
|
|||||||
EVT_BUTTON(wxID_OK, ExportPCMOptions::OnOK)
|
EVT_BUTTON(wxID_OK, ExportPCMOptions::OnOK)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
///
|
ExportPCMOptions::ExportPCMOptions(wxWindow * WXUNUSED(parent), int selformat)
|
||||||
///
|
|
||||||
ExportPCMOptions::ExportPCMOptions(wxWindow *parent, int selformat)
|
|
||||||
: wxDialog(NULL, wxID_ANY,
|
: wxDialog(NULL, wxID_ANY,
|
||||||
wxString(_("Specify Uncompressed Options")))
|
wxString(_("Specify Uncompressed Options")))
|
||||||
{
|
{
|
||||||
@ -149,10 +147,9 @@ ExportPCMOptions::ExportPCMOptions(wxWindow *parent, int selformat)
|
|||||||
sel = 0;
|
sel = 0;
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
mHeaderNames.Add(sf_header_index_name(i));
|
mHeaderNames.Add(sf_header_index_name(i));
|
||||||
if ((format & SF_FORMAT_TYPEMASK) == sf_header_index_to_type(i)) {
|
if ((format & SF_FORMAT_TYPEMASK) == (int)sf_header_index_to_type(i))
|
||||||
sel = i;
|
sel = i;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
mHeaderFromChoice = sel;
|
mHeaderFromChoice = sel;
|
||||||
|
|
||||||
mEncodingFormats.Clear();
|
mEncodingFormats.Clear();
|
||||||
@ -167,10 +164,10 @@ ExportPCMOptions::ExportPCMOptions(wxWindow *parent, int selformat)
|
|||||||
|
|
||||||
mEncodingNames.Add(sf_encoding_index_name(i));
|
mEncodingNames.Add(sf_encoding_index_name(i));
|
||||||
mEncodingFormats.Add(enc);
|
mEncodingFormats.Add(enc);
|
||||||
if ((format & SF_FORMAT_SUBMASK) == sf_encoding_index_to_subtype(i)) {
|
if ((format & SF_FORMAT_SUBMASK) == (int)sf_encoding_index_to_subtype(i))
|
||||||
mEncodingFromChoice = sel;
|
mEncodingFromChoice = sel;
|
||||||
}
|
else
|
||||||
else sel++;
|
sel++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,8 +179,7 @@ ExportPCMOptions::ExportPCMOptions(wxWindow *parent, int selformat)
|
|||||||
Fit();
|
Fit();
|
||||||
Center();
|
Center();
|
||||||
}
|
}
|
||||||
///
|
|
||||||
///
|
|
||||||
void ExportPCMOptions::PopulateOrExchange(ShuttleGui & S)
|
void ExportPCMOptions::PopulateOrExchange(ShuttleGui & S)
|
||||||
{
|
{
|
||||||
S.StartHorizontalLay(wxEXPAND, true);
|
S.StartHorizontalLay(wxEXPAND, true);
|
||||||
@ -215,9 +211,7 @@ void ExportPCMOptions::PopulateOrExchange(ShuttleGui & S)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
void ExportPCMOptions::OnHeaderChoice(wxCommandEvent & WXUNUSED(evt))
|
||||||
///
|
|
||||||
void ExportPCMOptions::OnHeaderChoice(wxCommandEvent & evt)
|
|
||||||
{
|
{
|
||||||
int format = sf_header_index_to_type(mHeaderChoice->GetSelection());
|
int format = sf_header_index_to_type(mHeaderChoice->GetSelection());
|
||||||
mEncodingNames.Clear();
|
mEncodingNames.Clear();
|
||||||
@ -264,15 +258,12 @@ void ExportPCMOptions::OnHeaderChoice(wxCommandEvent & evt)
|
|||||||
ValidatePair(GetFormat());
|
ValidatePair(GetFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
void ExportPCMOptions::OnChoice(wxCommandEvent & WXUNUSED(event))
|
||||||
///
|
|
||||||
void ExportPCMOptions::OnChoice(wxCommandEvent & event)
|
|
||||||
{
|
{
|
||||||
|
// ANSWER-ME: Why is this here?
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
void ExportPCMOptions::OnOK(wxCommandEvent& WXUNUSED(event))
|
||||||
///
|
|
||||||
void ExportPCMOptions::OnOK(wxCommandEvent& event)
|
|
||||||
{
|
{
|
||||||
WriteExportFormatPref(GetFormat());
|
WriteExportFormatPref(GetFormat());
|
||||||
|
|
||||||
@ -335,10 +326,12 @@ public:
|
|||||||
int subformat = 0);
|
int subformat = 0);
|
||||||
// optional
|
// optional
|
||||||
wxString GetExtension(int index = 0);
|
wxString GetExtension(int index = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
char *ConvertTo7bitASCII(const char *pSrc);
|
||||||
bool AddStrings(AudacityProject *project, SNDFILE *sf, Tags *tags);
|
bool AddStrings(AudacityProject *project, SNDFILE *sf, Tags *tags);
|
||||||
void AddID3Chunk(wxString fName, Tags *tags);
|
void AddID3Chunk(wxString fName, Tags *tags, int sf_format);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -583,9 +576,9 @@ int ExportPCM::Export(AudacityProject *project,
|
|||||||
buffer));
|
buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) {
|
if (((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) ||
|
||||||
AddID3Chunk(fName, metadata);
|
((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV))
|
||||||
}
|
AddID3Chunk(fName, metadata, sf_format);
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
wxFileName fn(fName);
|
wxFileName fn(fName);
|
||||||
@ -596,39 +589,125 @@ int ExportPCM::Export(AudacityProject *project,
|
|||||||
return updateResult;
|
return updateResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExportPCM::AddStrings(AudacityProject *project, SNDFILE *sf, Tags *tags)
|
char *ExportPCM::ConvertTo7bitASCII(const char *pSrc)
|
||||||
|
{
|
||||||
|
BYTE c;
|
||||||
|
int sz = strlen(pSrc);
|
||||||
|
|
||||||
|
char *pDest = (char *)malloc(sz+1);
|
||||||
|
char *pD = pDest;
|
||||||
|
|
||||||
|
if (!pDest)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// ISO Latin to 7 bit ascii conversion table (best approximation)
|
||||||
|
char aASCII7Table[256] = {
|
||||||
|
0x00, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||||
|
0x5f, 0x09, 0x0a, 0x5f, 0x0d, 0x5f, 0x5f, 0x5f,
|
||||||
|
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||||
|
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||||
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||||
|
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||||
|
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||||
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||||
|
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||||
|
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||||
|
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||||
|
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||||
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||||
|
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||||
|
0x45, 0x20, 0x2c, 0x53, 0x22, 0x2e, 0x2b, 0x2b,
|
||||||
|
0x5e, 0x25, 0x53, 0x28, 0x4f, 0x20, 0x5a, 0x20,
|
||||||
|
0x20, 0x27, 0x27, 0x22, 0x22, 0x2e, 0x2d, 0x5f,
|
||||||
|
0x22, 0x54, 0x73, 0x29, 0x6f, 0x20, 0x7a, 0x59,
|
||||||
|
0x20, 0x21, 0x63, 0x4c, 0x6f, 0x59, 0x7c, 0x53,
|
||||||
|
0x22, 0x43, 0x61, 0x22, 0x5f, 0x2d, 0x43, 0x2d,
|
||||||
|
0x6f, 0x7e, 0x32, 0x33, 0x27, 0x75, 0x50, 0x27,
|
||||||
|
0x2c, 0x31, 0x6f, 0x22, 0x5f, 0x5f, 0x5f, 0x3f,
|
||||||
|
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43,
|
||||||
|
0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49,
|
||||||
|
0x44, 0x4e, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x78,
|
||||||
|
0x4f, 0x55, 0x55, 0x55, 0x55, 0x59, 0x70, 0x53,
|
||||||
|
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x63,
|
||||||
|
0x65, 0x65, 0x65, 0x65, 0x69, 0x69, 0x69, 0x69,
|
||||||
|
0x64, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x2f,
|
||||||
|
0x6f, 0x75, 0x75, 0x75, 0x75, 0x79, 0x70, 0x79
|
||||||
|
};
|
||||||
|
|
||||||
|
do {
|
||||||
|
c = (BYTE) *pSrc++;
|
||||||
|
*pD++ = aASCII7Table[c];
|
||||||
|
} while (c);
|
||||||
|
|
||||||
|
return pDest;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExportPCM::AddStrings(AudacityProject * WXUNUSED(project), SNDFILE *sf, Tags *tags)
|
||||||
{
|
{
|
||||||
if (tags->HasTag(TAG_TITLE)) {
|
if (tags->HasTag(TAG_TITLE)) {
|
||||||
sf_set_string(sf, SF_STR_TITLE, tags->GetTag(TAG_TITLE).mb_str(wxConvUTF8));
|
char * ascii7Str = ConvertTo7bitASCII((const char *)tags->GetTag(TAG_TITLE).mb_str());
|
||||||
|
if (ascii7Str) {
|
||||||
|
sf_set_string(sf, SF_STR_TITLE, ascii7Str);
|
||||||
|
free(ascii7Str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tags->HasTag(TAG_ARTIST)) {
|
if (tags->HasTag(TAG_ARTIST)) {
|
||||||
sf_set_string(sf, SF_STR_ARTIST, tags->GetTag(TAG_ARTIST).mb_str(wxConvUTF8));
|
char * ascii7Str = ConvertTo7bitASCII((const char *)tags->GetTag(TAG_ARTIST).mb_str());
|
||||||
|
if (ascii7Str) {
|
||||||
|
sf_set_string(sf, SF_STR_ARTIST, ascii7Str);
|
||||||
|
free(ascii7Str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tags->HasTag(TAG_COMMENTS)) {
|
if (tags->HasTag(TAG_COMMENTS)) {
|
||||||
sf_set_string(sf, SF_STR_COMMENT, tags->GetTag(TAG_COMMENTS).mb_str(wxConvUTF8));
|
char * ascii7Str = ConvertTo7bitASCII((const char *)tags->GetTag(TAG_COMMENTS).mb_str());
|
||||||
|
if (ascii7Str) {
|
||||||
|
sf_set_string(sf, SF_STR_COMMENT, ascii7Str);
|
||||||
|
free(ascii7Str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tags->HasTag(TAG_YEAR)) {
|
if (tags->HasTag(TAG_YEAR)) {
|
||||||
sf_set_string(sf, SF_STR_DATE, tags->GetTag(TAG_YEAR).mb_str(wxConvUTF8));
|
char * ascii7Str = ConvertTo7bitASCII((const char *)tags->GetTag(TAG_YEAR).mb_str());
|
||||||
|
if (ascii7Str) {
|
||||||
|
sf_set_string(sf, SF_STR_DATE, ascii7Str);
|
||||||
|
free(ascii7Str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags->HasTag(TAG_GENRE)) {
|
||||||
|
char * ascii7Str = ConvertTo7bitASCII((const char *)tags->GetTag(TAG_GENRE).mb_str());
|
||||||
|
if (ascii7Str) {
|
||||||
|
sf_set_string(sf, SF_STR_GENRE, ascii7Str);
|
||||||
|
free(ascii7Str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tags->HasTag(wxT("Copyright"))) {
|
if (tags->HasTag(wxT("Copyright"))) {
|
||||||
sf_set_string(sf, SF_STR_COPYRIGHT, tags->GetTag(wxT("Copyright")).mb_str(wxConvUTF8));
|
char * ascii7Str = ConvertTo7bitASCII((const char *)tags->GetTag(wxT("Copyright")).mb_str());
|
||||||
|
if (ascii7Str) {
|
||||||
|
sf_set_string(sf, SF_STR_COPYRIGHT, ascii7Str);
|
||||||
|
free(ascii7Str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tags->HasTag(wxT("Software"))) {
|
if (tags->HasTag(wxT("Software"))) {
|
||||||
sf_set_string(sf, SF_STR_SOFTWARE, tags->GetTag(wxT("Software")).mb_str(wxConvUTF8));
|
char * ascii7Str = ConvertTo7bitASCII((const char *)tags->GetTag(wxT("Software")).mb_str());
|
||||||
|
if (ascii7Str) {
|
||||||
|
sf_set_string(sf, SF_STR_SOFTWARE, ascii7Str);
|
||||||
|
free(ascii7Str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportPCM::AddID3Chunk(wxString fName, Tags *tags)
|
void ExportPCM::AddID3Chunk(wxString fName, Tags *tags, int sf_format)
|
||||||
{
|
{
|
||||||
#ifdef USE_LIBID3TAG
|
#ifdef USE_LIBID3TAG
|
||||||
|
|
||||||
struct id3_tag *tp = id3_tag_new();
|
struct id3_tag *tp = id3_tag_new();
|
||||||
|
|
||||||
wxString n, v;
|
wxString n, v;
|
||||||
@ -656,6 +735,9 @@ void ExportPCM::AddID3Chunk(wxString fName, Tags *tags)
|
|||||||
else if (n.CmpNoCase(TAG_TRACK) == 0) {
|
else if (n.CmpNoCase(TAG_TRACK) == 0) {
|
||||||
name = ID3_FRAME_TRACK;
|
name = ID3_FRAME_TRACK;
|
||||||
}
|
}
|
||||||
|
else if (n.CmpNoCase(wxT("composer")) == 0) {
|
||||||
|
name = "TCOM";
|
||||||
|
}
|
||||||
|
|
||||||
struct id3_frame *frame = id3_frame_new(name);
|
struct id3_frame *frame = id3_frame_new(name);
|
||||||
|
|
||||||
@ -712,14 +794,15 @@ void ExportPCM::AddID3Chunk(wxString fName, Tags *tags)
|
|||||||
id3_tag_delete(tp);
|
id3_tag_delete(tp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ((len % 2) != 0) len++; // Length must be even.
|
||||||
id3_byte_t *buffer = (id3_byte_t *)malloc(len);
|
id3_byte_t *buffer = (id3_byte_t *)malloc(len);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
id3_tag_delete(tp);
|
id3_tag_delete(tp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
memset(buffer, 0, len); // Be clean for ending odd UTF16 content correctly.
|
||||||
|
|
||||||
len = id3_tag_render(tp, buffer);
|
id3_tag_render(tp, buffer);
|
||||||
|
|
||||||
id3_tag_delete(tp);
|
id3_tag_delete(tp);
|
||||||
|
|
||||||
@ -727,14 +810,22 @@ void ExportPCM::AddID3Chunk(wxString fName, Tags *tags)
|
|||||||
if (f.IsOpened()) {
|
if (f.IsOpened()) {
|
||||||
wxUint32 sz;
|
wxUint32 sz;
|
||||||
|
|
||||||
sz = wxUINT32_SWAP_ON_LE((wxUint32) len);
|
sz = (wxUint32) len;
|
||||||
f.SeekEnd(0);
|
f.SeekEnd(0);
|
||||||
|
if ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)
|
||||||
|
f.Write("id3 ", 4); // Must be lower case for foobar2000.
|
||||||
|
else {
|
||||||
f.Write("ID3 ", 4);
|
f.Write("ID3 ", 4);
|
||||||
|
sz = wxUINT32_SWAP_ON_LE(sz);
|
||||||
|
}
|
||||||
f.Write(&sz, 4);
|
f.Write(&sz, 4);
|
||||||
|
|
||||||
f.Write(buffer, len + (len & 0x01));
|
f.Write(buffer, len);
|
||||||
|
|
||||||
|
sz = (wxUint32) f.Tell() - 8;
|
||||||
|
if ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF)
|
||||||
|
sz = wxUINT32_SWAP_ON_LE(sz);
|
||||||
|
|
||||||
sz = wxUINT32_SWAP_ON_LE((wxUint32) f.Tell() - 8);
|
|
||||||
f.Seek(4);
|
f.Seek(4);
|
||||||
f.Write(&sz, 4);
|
f.Write(&sz, 4);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user