Help - Search - Members - Calendar
Full Version: Changes Made to TAG.EXE
Hydrogenaudio Forums > Hydrogenaudio Forum > Uploads
Pages: 1, 2
Synthetic Soul
Thinking about it, I think this will be because Tag understands MP3 files, but has no idea how to decypher TAK files (or OptimFrog, WavPack, and maybe more). Part of the extended information involves writing the duration of the track, and Tag can't retrieve that as it doesn't know how to read the header.

That said, I believe using -1 for the duration is valid (certainly for streaming files), so I may see if I can get Tag to use -1 for the duration if it can't decypher the format, and use the meta data info that it should surely know about.

I'll add it to my list of crap to stop me from doing proper work... wink.gif

Edit: FYI I have confirmed this. If Tag cannot obtain a duration it does not write the line at all. I'll report back here if I can make the change.


Synthetic Soul
OK, you can give Tag 2.0.52 a go.

This version should write #EXTINF for any file. If it doesn't understand the file type it will use -1 as the duration.

Edit: Removed beta status.
WaldoMonster
I use tag.exe to write the correct tags based on filenames with:

CODE
tag --auto --chreplace *.flac


I have changed the configuration file to mij needs (see below).
The autorenaming from ^ to ? works correct.
But somehow the conversion from ; to : doesn's work.
Must the ; be escaped or something?

CODE
# Specify character replacement for tagging
# note: space is separator
[CharReplacementForTag]
^ ?
; :


Synthetic Soul
I can confirm that this is the case, but can't immediately see why.

FYI: prefixing the semicolon works, so a replacement of "@; :" will convert "@;" to ":"; however ";@ :" does not work as expected.

It seems to be an issue with it beginning with ";". The ListSeparator is "; ", but I've checked in a hex editor and "^;^" results in 3F 3B 3F ("?;?"), not 3F 00 3F, as you would hope.

Dunno...

Here's the key code (taken from Tag.cpp) I believe (NB: swap is done in misc.cpp's ReplaceCharactersForTag):

CODE
case MCharReplaceTag:   // settings under [CharReplacementForTag]
    if ( (ReplaceTag->OldChars = (char **)realloc ( ReplaceTag->OldChars, sizeof (*ReplaceTag->OldChars) * (ReplaceTag->CharCount + 1) )) == NULL ) {
    fprintf ( stderr, "load_config: Memory allocation failed.\n" );
    exit (1);
    }
    if ( (ReplaceTag->NewChars = (char *)realloc ( ReplaceTag->NewChars, ReplaceTag->CharCount + 1 )) == NULL ) {
    fprintf ( stderr, "load_config: Memory allocation failed.\n" );
    exit (1);
    }
    p = temp;
    while ( *p && *p != ' ' ) p++;
    if ( (ReplaceTag->OldChars[ReplaceTag->CharCount] = (char *)malloc ( p - temp + 1 )) == NULL ) {
    fprintf ( stderr, "load_config: Memory allocation failed.\n" );
    exit (1);
    }
    if ( p > temp ) {
    strncpy ( ReplaceTag->OldChars[ReplaceTag->CharCount], temp, p-temp );
    }
    ReplaceTag->OldChars[ReplaceTag->CharCount][p-temp] = '\0';
    if ( *p == ' ' ) p++;
    ReplaceTag->NewChars[ReplaceTag->CharCount] = *p;
    ReplaceTag->CharCount++;
    break;





Synthetic Soul
Doh.

Just seen the real culprit just before that code in Tag.cpp:

CODE
    while ( fgets_clean ( temp, sizeof (temp), fp ) != EOF ) {
        if ( temp[0] == '\0' || temp[0] == ';' || temp[0] == '#' )  // skip empty lines and comments
            continue;

Not sure how to resolve this. It's possible to remove the check for ";", but what if people are using them for comment lines? I don't like to break backward compatibility. presumably "# :" wouldn't work either.

I can see no way to escape the character.
WaldoMonster
Thanks for the clear explanation.

I understand that you don't wont to break backwards compatibility.
A switch to disable the ; comment could be an option.
But maybe I'm the only one who really needed this feature.

Synthetic Soul
Well, users should really be able to swap any characters they choose.

I'd be tempted to stop ";" being a comment character just in that section. 1. The initial cfg file uses "#" so users may only think (as I did) that "#" is the only character that can be used (so no-one is using ";"). 2. "#" does not need replacing, as it is a valid filename character, so that can still be used.

If you agree I can easily create 2.0.53b1 and upload for you (and all new full releases will act in this way).
WaldoMonster
If I understood correctly than the ; will still be a comment tag.
But only in the [CharReplacementForTag] section you can use ;

That is really a good solution and still backwards compatible.
So I agree and would like doing some tests with the upcoming tag 2.0.53b1

Thanks for your help.
Synthetic Soul
You understand correctly. You can try 2.0.53b1.

FYI: all I have amended is:

CODE
if ( temp[0] == '\0' || (temp[0] == ';' && mode != MCharReplaceTag) || temp[0] == '#' )  // skip empty lines and comments

WaldoMonster
Simply fixes are mostly the best wink.gif
Everything seems to work as expected.

If I find something strange I will post it here.
I don't think that will happen with such a straightforward fix.

Thanks again.
WaldoMonster
I have done some test the last days with tag 2.0.53b1 and everything related to the ; renaming worked perfectly.

With double albums I discovered that tag.exe gave the album tag a cd number like below:

CODE
Filename                      Album tag
101 - Album name.extension    Album name (CD 1)
102 - Album name.extension    Album name (CD 1)
201 - Album name.extension    Album name (CD 2)
202 - Album name.extension    Album name (CD 2)


Can this behaviour somehow be configured or is this hard coded in the program?
Synthetic Soul
It looks to me as though there is a way to get the value into a Disc tag instead, but I can't work out how. smile.gif

The relevant code is in "guess.cpp".

FYI, according to the code %D for Disc is a valid token, although it's not documented in the CFG file.

I can't work out from the code what you're supposed to do to get the disc tag instead of it appending " (CD x)" to the album name.

Edit: Got it. I don't know what I was doing wrong.

CODE
tag --auto --scheme "%L\%D%N - %T" "204 - Track name.wv"

CODE
Tag - Automatic Tag from filename
Copyright (c) 2002-2003 Case.  Minor additions by Neil Popham, 2004-2007
Version 2.0.53b1, Compiled 2007-05-07

C:\Documents and Settings\Neil\Desktop\204 - Track name.wv
Tag:     Generated from name
Title:   Track name
Artist:
Album:   Desktop
Year:
Track:   04
Genre:
Comment:
Disc=2
APE v2.0 tag written.

WaldoMonster
I don't want to be a pain in the arse wink.gif
But still I found a problem with tag.

CODE
tag --auto --chreplace --scheme "%A\%Y - %L\%D%N - %T" *.flac

When using the command line like this the "Vorbis comment" block is written as below:

CODE
METADATA block #2
  type: 4 (VORBIS_COMMENT)
  is last: false
  length: 316
  vendor string: reference libFLAC 1.1.4 20070213
  comments: 11
    comment[0]: REPLAYGAIN_REFERENCE_LOUDNESS=89.0 dB
    comment[1]: REPLAYGAIN_TRACK_GAIN=-6.36 dB
    comment[2]: REPLAYGAIN_TRACK_PEAK=0.98138428
    comment[3]: REPLAYGAIN_ALBUM_GAIN=-6.48 dB
    comment[4]: REPLAYGAIN_ALBUM_PEAK=0.98852539
    comment[5]: Disc=2
    comment[6]: TITLE=Hatoa
    comment[7]: ARTIST=Bonobo
    comment[8]: ALBUM=Days to come
    comment[9]: TRACKNUMBER=07
    comment[10]: DATE=2006
METADATA block #3
  type: 1 (PADDING)
  is last: true
  length: 3820


The %D is written as "Disc", I think that this must be "DISCNUMBER" for "Vorbis comment".
When using the same line "%A\%Y - %L\%D%N - %T" in the [Schemes] section of tag.cfg it doesn't work at all.
vasya_pupkin
I have a feature request. Tag currently doesn't work properly with tracknumbers like "01/19" when renaming. It just renames file to "01-19 (something)". It would be better if it would rename file to "01 (something)" in this case.
Synthetic Soul
QUOTE(WaldoMonster @ May 11 2007, 19:10) *
The %D is written as "Disc", I think that this must be "DISCNUMBER" for "Vorbis comment".
When using the same line "%A\%Y - %L\%D%N - %T" in the [Schemes] section of tag.cfg it doesn't work at all.
I can easily (I think) change it to write Discnumber for all formats. I'm tempted by this, as IIRC it is the suggested filed name for that data. I'm confused why foobar uses Disc now, when I thought that it had previously moved from Disc to Discnumber.

The code that creates the disc tag has the comment "// quick hack". smile.gif I'm not confident about copying this to the other functions, that deal with the schemes and auto tagging.

QUOTE(vasya_pupkin @ May 11 2007, 19:36) *
I have a feature request. Tag currently doesn't work properly with tracknumbers like "01/19" when renaming. It just renames file to "01-19 (something)". It would be better if it would rename file to "01 (something)" in this case.
I'm sorry, but this is beyond me. sad.gif
vasya_pupkin
QUOTE(Synthetic Soul @ May 11 2007, 23:48) *
I'm sorry, but this is beyond me. sad.gif

Ok, can you please try this patch? I was unable to build all this mess because of libFLAC.

CODE
--- guess-old.cpp    2005-06-12 20:37:10.000000000 +0400
+++ guess.cpp    2007-05-12 03:11:51.981339500 +0400
@@ -678,6 +678,7 @@
     char    temp    [_MAX_PATH * 2 + 1];
     char    tempname[4096];
     char*   src   = NULL;
+    char*   sl;
     char*   f;
     size_t  s_pos = 0;
     size_t  i;
@@ -713,8 +714,14 @@
         }

         if ( src != NULL ) {
-            if ( src == TagValue ( APE_TAG_FIELD_TRACK, Info ) && (strlen (src) == 1) ) {
-                *f++ = '0';
+            if ( src == TagValue ( APE_TAG_FIELD_TRACK, Info ) ) {
+                if (strlen (src) == 1) {
+                    *f++ = '0';
+                }
+                sl = strchr ( src, '/' );
+                if ( sl != NULL ) {
+                  strncpy ( sl, '\0', 1 );
+                }
             }

             f += sprintf ( f, "%s", src );
Synthetic Soul
QUOTE(vasya_pupkin @ May 12 2007, 00:59) *

Ok, can you please try this patch? I was unable to build all this mess because of libFLAC.
Your patch causes an application error.

NB: I have written a guide regarding how to set up the source structure to build Tag. I did this ages ago, as it took me so long to just work out how to compile it when I made my first changes; it may be obvious to you. The guide can be found here:

http://www.synthetic-soul.co.uk/tag/setup.txt

It seems pretty f***ed up that you, as a C programmer, should be asking me, a non-C programmer, to make changes. smile.gif If you know C and want changes, do it!

As I've said many times now, I find my lack of knowledge frustrating, and trying to action people's requests is now just pissing me off. I wish I'd stopped at version 2.0.40 sometimes. I rarely even use Tag, although I do find it very useful to check what foobar is up to.

Sorry, don't mean to rant, and it's not aimed at you specifically.

Edit: Hang on, now I bother to look at your code, you never end up doing anything with sl do you?
vasya_pupkin
QUOTE(Synthetic Soul @ May 12 2007, 10:23) *
Your patch causes an application error.

Oops... smile.gif

QUOTE
It seems pretty f***ed up that you, as a C programmer, should be asking me, a non-C programmer, to make changes. smile.gif If you know C and want changes, do it!

I'm not a C programmer. In fact, I don't know C at all. I just analized the code and made a change that could do the thing in theory. But I could mess up something with pointers because I don't know how they work in C.

I will try your guide, maybe it'll help me to find those missing headers libFLAC wants. smile.gif
Synthetic Soul
QUOTE(vasya_pupkin @ May 12 2007, 13:08) *
I'm not a C programmer. In fact, I don't know C at all. I just analized the code and made a change that could do the thing in theory. But I could mess up something with pointers because I don't know how they work in C.
Ah, I see. Seems like we are in the same boat.
vasya_pupkin
QUOTE(Synthetic Soul @ May 12 2007, 10:23) *
Your patch causes an application error.

I found why. Replace
CODE
+                  strncpy ( sl, '\0', 1 );

with
CODE
+                  strncpy ( sl, "\0", 1 );


How could I do such a stupid mistake? smile.gif

PS: I spent an hour trying to build it with VS2003, but ended up with nothing. Everything builds but linker shows errors. So, it's again an unverified patch.. Hope it'll work this time.. smile.gif
Synthetic Soul
That appears to work.

Shouldn't it still pad the number though?


Edit: S'OK, I just changed it to:

CODE
if ( src == TagValue ( APE_TAG_FIELD_TRACK, Info ) ) {
    sl = strchr ( src, '/' );
    if ( sl != NULL ) {
        strncpy ( sl, "\0", 1 );
    }
    if (strlen (src) == 1) {
        *f++ = '0';
    }
}


2.0.53b2
vasya_pupkin
Thank you very much! It works! smile.gif
odyssey
Ummm, is it possible to avoid printing the copyright notice? Currently it outputs to the screen no matter what.
Synthetic Soul
I don't think that you can, but I don't think that you need to. You may want to look at --stdout.

Using that switch you can output the important bits to STDOUT, and leave the header writing to STDERR (IIRC).

E.g.:

CODE
TAG.EXE --stdout --hideinfo --hidenames file.mp3 > tags.txt

A1S
Thanks for the tool. Will not prompt, how I can write a cover in a wv-file? Whether it is possible to register separate tags (for example Cover Art (Front) and Cover Art (Back))?
odyssey
QUOTE(Synthetic Soul @ Oct 31 2007, 21:03) *

I don't think that you can, but I don't think that you need to. You may want to look at --stdout.

Using that switch you can output the important bits to STDOUT, and leave the header writing to STDERR (IIRC).

E.g.:

CODE
TAG.EXE --stdout --hideinfo --hidenames file.mp3 > tags.txt



I figured that was the only way I could direct the output to a textfile, but it's still being displayed on the screen (it usually should not when the output is directed).

It's just a nice-to-have feature, but I created a backup-script that would save all tags to dummy-files, and it would be nice if I could disable output to the screen (while directing the output to a file using pipes, like default commandline applications act), to simplify the process window.
Synthetic Soul
QUOTE(odyssey @ Oct 31 2007, 17:13) *
Ummm, is it possible to avoid printing the copyright notice? Currently it outputs to the screen no matter what.
No, AFAIK.

QUOTE(A1S @ Nov 26 2007, 13:23) *
Thanks for the tool. Will not prompt, how I can write a cover in a wv-file? Whether it is possible to register separate tags (for example Cover Art (Front) and Cover Art (Back))?
You cannot write binary tags, AFAIK.
A1S
QUOTE(Synthetic Soul @ Nov 26 2007, 19:38) *

QUOTE(A1S @ Nov 26 2007, 13:23) *
Thanks for the tool. Will not prompt, how I can write a cover in a wv-file? Whether it is possible to register separate tags (for example Cover Art (Front) and Cover Art (Back))?
You cannot write binary tags, AFAIK.

There is no possibility to make such option? Very-very big request. In foobar2000 0.9.5 there was a support Embedded album art.
Synthetic Soul
There is every possibility, but very little probability.

It is something that I would like to see in Tag, but I don't think that I have the time or skill to implement it.
A1S
But can all the same it will be possible? smile.gif We by means of a script, using tag.exe and ImgBurn.exe, do a backup copy of audio-disk with all tags (cuesheet,logfile,genre,discid...) in a format wv.iso.wv (process completely automatic). The only thing of that does not suffice is tag Cover Art. sad.gif
Synthetic Soul
It is obviously possible for an accomplished C(++) programmer to add binary tag support to Tag; if MP3Tag can do it then there is no logical reason why another application cannot.

This post documents the format that MP3Tag uses.
ntan01
I am having a technical problem with tag.exe.

My question involves the --allow switch on the command line. I have an automated process that records mp3's and dumps them in various directories based on a criteria setup in the recording process. I want to use tag.exe to pull information from the file path and insert it into the tags. I've gotten this much to work just fine.
My problem is that mp3's are constantly being recorded and added to the directories. I would like to schedule a task to run tag every X minutes that crawls the directories and only processes those files that do not have tag information yet. (basically anything added since the last time tag was ran)
I'm assuming that I use --allow to accomplish this, but I'm not sure how to represent a null value. --allow "album=" doesn't seem to do the trick.

Any suggestions?

Synthetic Soul
--allow will check for an exact match, and that's all. I'm not sure that it is any use to you.

I don't know what scripting language you are using, but I would probably look to using Tag's --tostdoutn switch, to output the value of a specific tag to STDOUT - checking to see whether the value was empty or not and acting accordingly.

Here is a simple DOS example, that will check for the existence of the Artist tag in all MP3s in a directory, and its subdirectories:

CODE
@ECHO OFF

FOR /R %1 %%G IN (*.mp3) DO CALL :CheckArtist "%%G"

PAUSE

GOTO :EOF

:CheckArtist
    CALL :GetTag Artist %1
    IF [] EQU [%Artist%] ECHO %1 has no Artist field.
GOTO :EOF

:GetTag
    TAG.EXE --tostdoutn %1 --hideinfo --hidetags --hidenames %2>"%TEMP%\tmp.txt"
    SET /P %1=<"%TEMP%\tmp.txt"
    DEL "%TEMP%\tmp.txt"
GOTO :EOF

(Save as a BAT file and drag the root folder onto the icon to test - or pass the folder path as a parameter on the command line.)
ntan01
Thanks. When I drag and drop, it works fine, but I'm having troubles getting it to run from the command line.

This is probably a total noob question, but how do I get this to work from the command line. I tried:
foo.bat c:\mp3\
and that didn't work. But if I drag the mp3 folder to the foo.bat, it works fine.

What am I doing wrong?

Thanks,
-Nate
Synthetic Soul
It may be to do with the path to Tag.

Try changing the line that calls Tag to use the full path - or ensure that Tag is in a folder in your PATH (like your Windows folder).

That's all I can think of - it works fine for me either way (I have Tag in my Windows directory).
odyssey
Is it impossible to remove all tags from a file, while tagging specific fields?

I would expect using --remove with -t item=x would erase all existing fields and only leave the specified, but it seem to disregard the --remove parameter.
Paul Burger
Hi Synthetic Soul,

First of all, thanks for keeping TAG alive and all the work you did on REACT2!

I can get Tag to create a playlist using the REACT2. (as per the wiki post).

My idea behind creating playlists is to create a "playlist" directory for each compression type in the parent directory of the specific compression type.

For example;
..\Music\MP3\Playlists\ > contains all mp3 playlists and
..\Music\MP3\ > contains all the album directories

These playlists should therefore reference ..\"Artist - Album [Year]"\"TrackNo. TrackName".mp3. That is if I understand playlists correctly.

The idea is to copy the entire directory (e.g. MP3, Ogg or Flac) to whatever player I'm using, so when I want to play anything I simply browse the playlist directory to find the appropriate (custom or album) playlist.

I tried to get this done with Tag but it does not seem to support directory references.

If this cannot be done in Tag, can you possibly recommend something else?

Thanks
Paul
noorotic
Synthetic Soul, I had not checked this thread in a long time. If it is needed, I have the C code for importing and exporting binary (images) into APEv2 tags. I am not sure I know the Tag code well enough to insert into it however. Also, it would create a feature for APE not supplied by Tag for other tag types.

I personally do not care much for the embedding of artwork, for myself. It seemed like a fun thing to do. I have wondered why, since all tag formats provide for URL, and having followed the thread on artwork in the Foobar forum a bit, it would not be best simply to set the URL bit and allow people to point the player to the local file they want. Seems much more efficient.

However since most of Tag is C (I haven't picked up C++ yet) I think my import/export functions should work if integrated into Tag's code.

I'll check back some time. thx
Synthetic Soul
QUOTE(Paul Burger @ Aug 5 2008, 13:14) *
I tried to get this done with Tag but it does not seem to support directory references.

If this cannot be done in Tag, can you possibly recommend something else?
No, it doesn't look like it does.

I guess that you could just use ECHO commands in your config to append to a playlist, e.g.:

CODE
ECHO $cdartist$ - $album$ [$date$]\$track$ - $title$.mp3>>@OutRoot@\Music\MP3\Playlists\$cdartist$ - $album$.m3u

You may have to escape some characters though, otherwise ampersands (for example) will cause problems. Certainly a possibility though.

QUOTE(noorotic @ Aug 5 2008, 16:10) *
Synthetic Soul, I had not checked this thread in a long time. If it is needed, I have the C code for importing and exporting binary (images) into APEv2 tags. I am not sure I know the Tag code well enough to insert into it however. Also, it would create a feature for APE not supplied by Tag for other tag types.
I would like to see support for embedding images in Tag; however, as you say, it would be wrong to add it for APEv2 only. Also, I'm not sure that I would have the where-with-all (or inclination) to insert the code. Thanks for the thought though. I must admit that I have lost an interest in doing anything else with Tag.
Synthetic Soul
Off-topic posts regarding REACT moved to a new thread.
Lurkas
TAG doesn't write ID3v2.3 tags. The source is out there, have anyone seen a build capable of writing those tags?

I wish someone could implement it..
Synthetic Soul
Would metamp3 (search this board) be of any use?
Lurkas
Thanks for the notification but I had a look at it last night. It doesn't look like it has the character replace function and tags from file name.
greynol
QUOTE(Lurkas @ Aug 7 2008, 05:47) *
TAG doesn't write ID3v2.3 tags.

I'm using tag.exe with Lame and am getting ID3v2 tags with no trouble at all.
Lurkas
That sounds interesting. Can someone please explain how to do that?
greynol
CODE
tag %1 2> "%~1.tag"
FOR /F "usebackq tokens=1*" %%X IN (`findstr "Title:" "%~1.tag"`) DO (
SET title=%%Y
)
FOR /F "usebackq tokens=1*" %%X IN (`findstr "Artist:" "%~1.tag"`) DO (
SET artist=%%Y
)
FOR /F "usebackq tokens=1*" %%X IN (`findstr "Album:" "%~1.tag"`) DO (
SET album=%%Y
)
FOR /F "usebackq tokens=1*" %%X IN (`findstr "Year:" "%~1.tag"`) DO (
SET year=%%Y
)
FOR /F "usebackq tokens=1*" %%X IN (`findstr "Track:" "%~1.tag"`) DO (
SET track=%%Y
)
FOR /F "usebackq tokens=1*" %%X IN (`findstr "Genre:" "%~1.tag"`) DO (
SET genre=%%Y
)
FOR /F "usebackq tokens=1*" %%X IN (`findstr "Comment:" "%~1.tag"`) DO (
SET comment=%%Y
)
SET TAGINFO=--add-id3v2 --tt "%title%" --ta "%artist%" --tl "%album%" --ty "%year%" --tn "%track%" --tg "%genre%" --tc "%comment%"
DEL "%~1.tag"
Lurkas
Thank you for your reply greynol. I assume that's a batch script. I'm not really sure on how to use that. Can you please give a verbose example on how to use it in a commandline?
greynol
It's a subroutine to be used in a batch script, though you can use it as a separate script. You call the routine and pass it the name and path of the source file. It will then generate a variable called TAGINFO which you would use in your Lame command line.

Example assuming this is a separate script called id3v2tag.bat and a source file called c:\stuff\source.flac

id3v2tag c:\stuff\source.flac

let's assume you have created source.wav (though I don't do it this way)

lame -V5 %TAGINFO% c:\stuff\source.wav c:\stuff\source.mp3

EDIT: Here's an example of a similar routine put to use in a script to encode using neroAacEnc:
http://www.hydrogenaudio.org/forums/index....st&p=580029
Lurkas
Can I get this to work with wildcards, and what syntax to use if so?

Is it possible to just tag an encoded file with lame.exe? I've only pulled it off while encoding..
greynol
>Can I get this to work with wildcards, and what syntax to use if so?
You can't pass a wildcard to the script as it currently exists.

>Is it possible to just tag an encoded file with lame.exe?
No.

Please, no more questions about batch scripts. Let's keep this discussion on topic. Synthetic Soul has had to split this thread once already.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2008 Invision Power Services, Inc.