TAG_ID3 (из Bass 2.4.4) не работает должным образом

Я пытаюсь прочитать теги ID3v1 из mp3-файлов, используя «BASS.dll» (через bass.lib и bass.h).
Работает нормально, пока файл .mp3 не имеет заголовка (или исполнителя), содержащего 30 символов.
Вместо
Happy Times (Feat. Margaux Bos
я получил Happy Times (Feat. Margaux BosEmigrate
с Emigrate добавлено (это тег исполнителя).

Как сделать так, чтобы он работал правильно, без добавления тега Artist?
Вот мой исходный код:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"#include "bass.h"//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"TForm2 *Form2;

//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
BASS_Init(-1, 44000, 0, 0, 0);

if(OpenDialog1->Execute())
{
HSTREAM stream = BASS_StreamCreateFile(false, OpenDialog1->FileName.c_str(), 0, 0, 0);
TAG_ID3 *tags = (TAG_ID3*)BASS_ChannelGetTags(stream, BASS_TAG_ID3);
Edit1->Text = tags->title;
}
}

0

Решение

Текстовые поля TAG_ID3 Не гарантируется, что struct завершается нулем, но ваш код обрабатывает их так, как если бы они были, поэтому он завершает чтение следующего поля, когда отсутствует нулевой терминатор. Чтобы это исправить, вы должны принять во внимание их максимальную длину, например:

Edit1->Text = AnsiString().sprintf("%.*s", sizeof(tags->title), tags->title);

Или же:

Edit1->Text = AnsiString(tags->title, sizeof(tags->title)).TrimRight();

То же самое со всеми другими текстовыми полями:

  • id: 3 символа
  • title: 30 символов
  • artist: 30 символов
  • album: 30 символов
  • year: 4 символа
  • comment: 30 символов

Вы можете использовать простую обертку шаблона, чтобы помочь вам:

template<size_t N>
String toString(char (&arr)[N])
{
return AnsiString().sprintf("%.*s", N, arr);
/* or:
return AnsiString(arr, N).TrimRight();
*/
}

Edit1->Text = toString(tags->title);

Обратите внимание, что comment поле имеет дополнительное предостережение:

Если 30-й символ является ненулевым, а 29-й — нулевым, то 30-й символ является номером дорожки, и комментарий ограничен первыми 28 символами.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector