Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: My regression test script shows strange behaviour - is there a tag mapping table? #293

Closed
sandreas opened this issue Dec 4, 2024 · 4 comments
Labels

Comments

@sandreas
Copy link
Contributor

sandreas commented Dec 4, 2024

Hey there,

I wrote a little script for tone to do regression tests. It's a dirty hack before I write real unit tests but I wanted something that tests the behaviour of the compiled program without having to do too much work.

Basically it writes the value 1 in every property that atldotnet supports.

However, the results where interesting and I wanted to share them - not having in mind to fix something, but to ask the question, if there is a documentation for kind of a mapping table containing:

  1. metadata format and the according frame mapping (like TALB is used for Album) of that format
  2. The internal property name of Track

Where is an example what I have in mind:

ATL Track Property ID3v2.3 ID3v2.4 MP4 ....
Album TALB TALB albm ....
... ... ... ... ....

I would put in some effort to help with this (e.g. in the Wiki), because I think it would be worth and because I already have something similar for my projects. Maybe I could even do this programmatically via frameMapping of the different formats to keep the list up to date.

For some formats, fields are not supported or just do nothing when writing.

Here is the script

Required to run it:

  • tone, jq and unix tools like sed, find, etc
  • a bunch of sample files from your Resources directory (e.g. flac, m4a and mp3)
#!/bin/sh

PROPERTIES_TO_TEST="album albumArtist artist bpm chaptersTableDescription comment composer conductor copyright description discNumber discTotal encodedBy encoderSettings encodingTool genre group longDescription movement movementName originalAlbum originalArtist part popularity publisher sortTitle sortAlbum sortArtist sortAlbumArtist sortComposer subtitle title trackNumber trackTotal"
AFTER_ADD_FILE="test_tag.json"
AFTER_REMOVE_FILE="test_removed.json"
mkdir -p var/samples/
rm -f var/samples/*
find samples -maxdepth 1 -type f -name '*.*' -exec cp {} var/samples \;

FILES="$(ls var/samples)"

FAIL=0
for F in $FILES; do
  ADD_PROPERTIES=""
  REMOVE_PROPERTIES=""
  FILE="var/samples/$F"
  
  echo "---- tagging file $F ----"
  for CCPROP in $PROPERTIES_TO_TEST; do
    PROPVALUE="1"
    
    PROP=$(echo "$CCPROP" | sed --expression 's/\([A-Z]\)/-\L\1/g' --expression 's/^-//')
    
    ADD_PROPERTIES=""$ADD_PROPERTIES" --meta-$PROP "$PROPVALUE""
    REMOVE_PROPERTIES=""$REMOVE_PROPERTIES" --meta-remove-property "$CCPROP""
  done
  
  rm -rf test_after*.meta
  
  tone tag "$FILE" $ADD_PROPERTIES > /dev/null
  tone dump $FILE --format=json --query \$.meta > "$AFTER_ADD_FILE"
  tone tag "$FILE" $REMOVE_PROPERTIES > /dev/null
  tone dump $FILE --format=json --query \$.meta > "$AFTER_REMOVE_FILE"

  for CCPROP in $PROPERTIES_TO_TEST; do
    value="$(jq .$CCPROP "$AFTER_ADD_FILE" | xargs | tr -d '.0')"
    if [ "$value" = "1" ]; then
      echo "  SUCCESS: property $CCPROP=$value"
    else
      echo "  FAIL: property $CCPROP=$value (expected: 1)"
      FAIL=1
    fi 
  done
  
  echo "---- removing tags from file $f ----"
  REMOVED_CONTENT="$(cat "$AFTER_REMOVE_FILE")"
  if [ "$REMOVED_CONTENT" = "{}" ]; then
    echo "  SUCCESS: removed all properties"
  else 
    echo "  FAIL: did not remove all properties"
    echo "$REMOVED_CONTENT"    
    FAIL=1
  fi
  
  echo "--------------------------------------"
done

echo "==================================="
if [ "$FAIL" = "1" ]; then
  echo "FAIL: errors while performing regression tests"
else
  echo "SUCCESS: all regression tests passed"
fi
And here the results
---- tagging file sample.flac ----
  SUCCESS: property album=1
  SUCCESS: property albumArtist=1
  SUCCESS: property artist=1
  FAIL: property bpm=null (expected: 1)
  FAIL: property chaptersTableDescription=null (expected: 1)
  SUCCESS: property comment=1
  SUCCESS: property composer=1
  SUCCESS: property conductor=1
  SUCCESS: property copyright=1
  SUCCESS: property description=1
  SUCCESS: property discNumber=1
  SUCCESS: property discTotal=1
  SUCCESS: property encodedBy=1
  FAIL: property encoderSettings=null (expected: 1)
  FAIL: property encodingTool=null (expected: 1)
  SUCCESS: property genre=1
  FAIL: property group=null (expected: 1)
  FAIL: property longDescription=null (expected: 1)
  FAIL: property movement=null (expected: 1)
  FAIL: property movementName=null (expected: 1)
  FAIL: property originalAlbum=null (expected: 1)
  FAIL: property originalArtist=null (expected: 1)
  FAIL: property part=null (expected: 1)
  SUCCESS: property popularity=1
  SUCCESS: property publisher=1
  FAIL: property sortTitle=null (expected: 1)
  FAIL: property sortAlbum=null (expected: 1)
  SUCCESS: property sortArtist=1
  SUCCESS: property sortAlbumArtist=1
  FAIL: property sortComposer=null (expected: 1)
  FAIL: property subtitle=null (expected: 1)
  SUCCESS: property title=1
  SUCCESS: property trackNumber=1
  SUCCESS: property trackTotal=1
---- removing tags from file  ----
  SUCCESS: removed all properties
--------------------------------------
---- tagging file sample.m4a ----
  SUCCESS: property album=1
  SUCCESS: property albumArtist=1
  SUCCESS: property artist=1
  FAIL: property bpm=null (expected: 1)
  FAIL: property chaptersTableDescription=null (expected: 1)
  SUCCESS: property comment=1
  SUCCESS: property composer=1
  SUCCESS: property conductor=1
  SUCCESS: property copyright=1
  SUCCESS: property description=1
  SUCCESS: property discNumber=1
  SUCCESS: property discTotal=1
  SUCCESS: property encodedBy=1
  FAIL: property encoderSettings=null (expected: 1)
  FAIL: property encodingTool=null (expected: 1)
  SUCCESS: property genre=1
  SUCCESS: property group=1
  SUCCESS: property longDescription=1
  SUCCESS: property movement=1
  SUCCESS: property movementName=1
  FAIL: property originalAlbum=null (expected: 1)
  FAIL: property originalArtist=null (expected: 1)
  SUCCESS: property part=1
  SUCCESS: property popularity=1
  SUCCESS: property publisher=1
  SUCCESS: property sortTitle=1
  SUCCESS: property sortAlbum=1
  SUCCESS: property sortArtist=1
  SUCCESS: property sortAlbumArtist=1
  FAIL: property sortComposer=null (expected: 1)
  FAIL: property subtitle=null (expected: 1)
  SUCCESS: property title=1
  SUCCESS: property trackNumber=1
  SUCCESS: property trackTotal=1
---- removing tags from file  ----
  SUCCESS: removed all properties
--------------------------------------
---- tagging file sample.mp3 ----
  SUCCESS: property album=1
  SUCCESS: property albumArtist=1
  SUCCESS: property artist=1
  FAIL: property bpm=null (expected: 1)
  FAIL: property chaptersTableDescription=null (expected: 1)
  SUCCESS: property comment=1
  SUCCESS: property composer=1
  SUCCESS: property conductor=1
  SUCCESS: property copyright=1
  FAIL: property description=null (expected: 1)
  SUCCESS: property discNumber=1
  SUCCESS: property discTotal=1
  SUCCESS: property encodedBy=1
  FAIL: property encoderSettings=null (expected: 1)
  FAIL: property encodingTool=null (expected: 1)
  FAIL: property genre=Classic Rock (expected: 1)
  SUCCESS: property group=1
  SUCCESS: property longDescription=1
  SUCCESS: property movement=1
  SUCCESS: property movementName=1
  SUCCESS: property originalAlbum=1
  SUCCESS: property originalArtist=1
  SUCCESS: property part=1
  SUCCESS: property popularity=1
  SUCCESS: property publisher=1
  SUCCESS: property sortTitle=1
  SUCCESS: property sortAlbum=1
  SUCCESS: property sortArtist=1
  SUCCESS: property sortAlbumArtist=1
  SUCCESS: property sortComposer=1
  SUCCESS: property subtitle=1
  SUCCESS: property title=1
  SUCCESS: property trackNumber=1
  SUCCESS: property trackTotal=1
---- removing tags from file  ----
  SUCCESS: removed all properties
--------------------------------------
===================================
FAIL: errors while performing regression tests

@Zeugma440
Copy link
Owner

There's no such documentation, but it shouldn't be too difficult to do.

  • Track fields are mapped to TagData.Field entries
  • Every class implementing IMetaData has its own mapping to the same entries (e.g. frameMapping_v22, frameMapping_v23 and frameMapping_v24 in the ID3v2 class)

My main reference for how to map standard tags is that page, plus all the feedback I've received over the years on the project.

Maybe I could even do this programmatically via frameMapping of the different formats to keep the list up to date.

I think that's definitely feasible and would be a nice way to put everything in one place without spending too much time copy/pasting 👍 Keep me informed~

@sandreas
Copy link
Contributor Author

sandreas commented Dec 5, 2024

Thank you for your quick response.

Keep me informed~

Yeah, I did work on an extension in my fork to do something like this programmatically.

What I found particularly interesting about the results of my script was:

---- tagging file sample.flac ----
  FAIL: property chaptersTableDescription=null (expected: 1)
  FAIL: property group=null (expected: 1)
  FAIL: property longDescription=null (expected: 1)
  FAIL: property movement=null (expected: 1)
  FAIL: property movementName=null (expected: 1)
  FAIL: property originalAlbum=null (expected: 1)
  FAIL: property originalArtist=null (expected: 1)
  FAIL: property sortTitle=null (expected: 1)
  FAIL: property sortAlbum=null (expected: 1)
  FAIL: property sortComposer=null (expected: 1)
  FAIL: property subtitle=null (expected: 1)


---- tagging file sample.m4a ----
  FAIL: property chaptersTableDescription=null (expected: 1)
  FAIL: property encoderSettings=null (expected: 1)
  FAIL: property originalAlbum=null (expected: 1)
  FAIL: property originalArtist=null (expected: 1)
  FAIL: property sortComposer=null (expected: 1)
  FAIL: property subtitle=null (expected: 1)


---- tagging file sample.mp3 ----
  FAIL: property chaptersTableDescription=null (expected: 1)
  FAIL: property description=null (expected: 1)
  FAIL: property genre=Classic Rock (expected: 1)

So my conclusion:

  • ID3v2 on mp3 seems to handle numeric genre internally and rewrites it into named ones
  • originalAlbum and originalArtist seems only to be supported by mp3 / id3v2, although mp4 should have ©ope atom for it (maybe thats an issue in tone)
  • chaptersTableDescription cannot be set without having chapters and even with chapters its strange (refer to How to identify CTOC (Table of Contents) chaps from mp3 sandreas/tone#50)
  • flac seems to use ApeTag v2 by default, which does not support group, longDescription, movement and others by default mapping.

I'm doing a bit more research, what is wrong with the FAIL things and report back.

@Zeugma440
Copy link
Owner

flac seems to use ApeTag v2 by default, which does not support group, longDescription, movement and others by default mapping.

Wasn't that supposed to be fixed by #289? Can you confirm you're using v6.09?

I'll take a closer look at the rest of the report soon.

@sandreas
Copy link
Contributor Author

sandreas commented Dec 5, 2024

I'll take a closer look at the rest of the report soon.

No need to hurry, I'm going to investigate this. Some of the properties (e.g. Bpm) are mapped manually via dirty hack in my DotnetLibAudioMetadata (see https://github.com/sandreas/DotnetLibAudioMetadata/blob/737dfaccb7bd34988c3dc3f8612afb6658f33f99/Sandreas.AudioMetadata/AudioMetadata/MetadataTrack.cs#L27)

This may be the problem - I don't want you to invest more time than required. I'm going to investigate this further and report single, well defined issues for each problem group to save you time.

Thank you :-)

@sandreas sandreas closed this as completed Dec 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants