Last updated 2022-07-25.
Script for Picard 2.7.0:
- You need to install the “Instruments” plugin by David Mandelberg.
$noop(Separating performers by instrument for Picard 2.7.0 w/ Instruments plugin)
$noop("instruments" and "additional instruments" ends up in performer)
$unset(performer)
$set(_instrumentsFieldName,instruments)
$noop(Picard is case sensitive, so MP3 TXXX tags must be manually handled - Picard apparently reads ALLCAPS m4a tags as lower case...)
$if($eq_any($upper(%_extension%),MP3),$set(_instrumentsFieldName,$upper(%_instrumentsFieldName%)))
$noop(I like to indicate whether these are track-level, release-level, or 'reduction by ear' credits. You need to manually fill this in.)
$set(_instrumentsPrecisionField,instruments precision)
$noop(Picard is case sensitive, so MP3 TXXX tags must be manually handled - Picard apparently reads ALLCAPS m4a tags as lower case...)
$if($eq_any($upper(%_extension%),MP3),$set(_instrumentsPrecisionField,$upper(%_instrumentsPrecisionField%)))
$foreach(%_instruments%,
$set(_currentInstrument,%_loop_value%)
$noop(Ignore misuse of instrument 0a06dd9a-92d6-4891-a699-2b116a3d3f37)
$if($eq($lower(%_currentInstrument%),other instruments),$set(_skipInstrument,1))
$if($eq($lower(%_currentInstrument%),all other instruments),$set(_skipInstrument,1))
$if($eq($lower(%_currentInstrument%),all other instruments & programming),$set(_skipInstrument,1))
$if($eq(%_skipInstrument%,1),,
$noop(Standardize instrument names to be used in tag field names)
$set(_standardizedInstrument,$lower(%_currentInstrument%))
$noop(Transliterate the field name for non-ASCII instruments)
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,irish harp / clàrsach,clarsach))
$noop(e.g., bandoneón)
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,ó,o))
$noop(e.g., agogô)
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,ô,o))
$noop(e.g., clàrsach)
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,à,a))
$noop(For compatibility, don't want any apostrophes in field names.)
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,',_))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,ギター,guitar))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,鍵盤ハーモニカ,melodica))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,二胡,erhu))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,尺八,shakuhachi))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,三味線,shamisen))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,琴,koto))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,能管,nohkan))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,篠笛,shinobue))
$noop(Note that 笛 doesn't always mean flute - it might be whistling vocals!)
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,笛,flute))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,コントラファゴット,contrabassoon))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,ファゴット,bassoon))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,スキャット,scat))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,コーラス,chorus))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,かけ声,shout))
$noop(Fix effectively-destructive edits to legacy data)
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,membranophone,drums))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,romantic guitar,gut guitar))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,guitar family,guitar))
$noop(Standardize credited names)
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,drums \(drum set\),drums))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,1st violin,violin))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,2nd violin,violin))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,3rd violin,violin))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,violin family,violin))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,violins,violin))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,violoncello,cello))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,vocals,vocal))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,lead vocal,vocal))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,rapper,rap))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,sub vocal,background vocal))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,sub chorus,background vocal))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,backing chorus,background vocal))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,fantastic chorus,background vocal))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,cho.,chorus))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,chorus,background vocal))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,background vocal master,chorus master))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,backing vocal,background vocal))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,vocal samples,vocal sample))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,vocal sample,vocal))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,guitars,guitar))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,e.guitar,electric guitar))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,a.guitar,acoustic guitar))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,w.bass,wood bass))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,a.saxophone,alto saxophone))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,b.saxophone,baritone saxophone))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,t.saxophone,tenor saxophone))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,sax section,sax))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,fagotto,bassoon))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,fagott,bassoon))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,tsugarushamisen,shamisen))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,cor anglais,oboe))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,english horn,oboe))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,percussions,percussion))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,pf,piano))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,keyboards,keyboard))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,synthesizers,synthesizer))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,mini moog,minimoog))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,blues harp,harmonica))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,prophet-5,analog synthesizer))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,sub 37,analog synthesizer))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,dx-7,synthesizer))
$set(_standardizedInstrument,$replace(%_standardizedInstrument%,emulator ii,synthesizer))
$noop(Set custom field's name)
$set(_currentCustomPerformerField,performer %_standardizedInstrument%)
$noop(Picard is case sensitive, so MP3 TXXX tags must be manually handled - Picard apparently reads ALLCAPS m4a tags as lower case...)
$if($eq_any($upper(%_extension%),MP3),$set(_currentCustomPerformerField,$upper(%_currentCustomPerformerField%)))
$set(_temp_currentCustomPerformerField,temp performer %_standardizedInstrument%)
$noop(If I set the instruments using 'reduction by ear', then don't download non-applicable performers.)
$set(_existingInstruments,$get(%_instrumentsFieldName%))
$set(_instruments_precision,$get(%_instrumentsPrecisionField%))
$if($eq(%_instruments_precision%,reduction by ear),
$if($find(%_existingInstruments%,%_standardizedInstrument%),,
$set(_skipInstrument,1)
)
)
$if($eq(%_skipInstrument%,1),,
$noop(Performer prefixes)
$foreach(; additional ; guest ; solo ; guest solo ,
$set(_currentInstrumentRegex,/^\(.*\, \)?\(.* and \)?%_loop_value%$replace($replace(%_currentInstrument%,\(,\\\(),\),\\\))\(\, .*\)?\( and .*\)?\$/)
$setmulti(_currentInstrumentMains,$performer(%_currentInstrumentRegex%, ), )
$foreach($unique(%_currentInstrumentMains%),
$set(_performer,%_loop_value%)
$noop(Standardize the musician names here, since it's not really possible to work on the performer names elsewhere)
$noop(Undo select fancy punctuation)
$set(_performer,$replace($get(_performer),‐,-))
$set(_performer,$replace($get(_performer),“,"))
$set(_performer,$replace($get(_performer),”,"))
$set(_performer,$replace($get(_performer),’,'))
$noop(Remove character from the vocal in CV credited names)
$if($rsearch(%_performer%,[(\\\(][CcCc][\\..]{0\,1}[VvVv][:\\.:.\\s]),
$set(_performer,$rreplace(%_performer%,\(.*\)\\s*\([(\\\(]\)\([CcCc][\\..]{0\,1}[VvVv]\)\([:\\.:.]\)\\s*\(.*\)\([)\\\)]\),\\5))
)
$noop(
$if($or($find(%_performer%,\(CV:),$find(%_performer%,\(CV.)),
$set(_performer,$rreplace(%_performer%,\(.*\)\\\(CV[.:]\(.*\)\\\),\\2))
)
$if($or($find(%_performer%,\(cv:),$find(%_performer%,\(cv.)),
$set(_performer,$rreplace(%_performer%,\(.*\)\\\(cv[.:]\(.*\)\\\),\\2))
)
)
$noop(Remove character from the vocal in Geneon-style starring credited names)
$if($find(%_performer%, starring ),
$set(_performer,$rreplace(%_performer%,\(.*\) starring \(.*\),\\2))
)
$noop(Remove BEMANI Sound Team)
$if($find(%_performer%,BEMANI Sound Team),
$set(_performer,$rreplace(%_performer%,BEMANI Sound Team ["“”]\(.*\)["“”],\\1))
)
$noop(Remove Konami Amusement)
$if($find(%_performer%,Konami Amusement),
$set(_performer,$rreplace(%_performer%,Konami Amusement \\\(\(.*\)\\\),\\1))
)
$noop(Remove Konami Digital Entertainment)
$if($find(%_performer%,Konami Digital Entertainment),
$set(_performer,$rreplace(%_performer%,Konami Digital Entertainment \\\(\(.*\)\\\),\\1))
)
$copymerge($get(_temp_currentCustomPerformerField),_performer)
)$noop(Close foreach performer in this performer prefix)
)$noop(Close foreach performer prefix)
$noop(Merge conflicts - remove local values not found in the server; add server values not found in local)
$set(_temp_ordered_currentCustomPerformerValues,)
$foreach($get(%_currentCustomPerformerField%),
$set(_oldPerformerValue,%_loop_value%)
$set(_foundOldPerformerValue,0)
$foreach($unique($get(%_temp_currentCustomPerformerField%)),
$if($eq(%_loop_value%,%_oldPerformerValue%),$set(_foundOldPerformerValue,1),)
)
$if($eq(%_foundOldPerformerValue%,1),$copymerge(_temp_ordered_currentCustomPerformerValues,_oldPerformerValue),)
)
$if(%_currentCustomPerformerField%,$delete(%_currentCustomPerformerField%))
$noop(Add old values that I may have manually ordered)
$copymerge(%_currentCustomPerformerField%,_temp_ordered_currentCustomPerformerValues)
$noop(Add new values not found in my local tag at the end)
$copymerge(%_currentCustomPerformerField%,%_temp_currentCustomPerformerField%)
$noop(
$if(%_temp_currentCustomPerformerField%,$delete(%_temp_currentCustomPerformerField%))
)
$copymerge(_temporaryPerformerFields,_temp_currentCustomPerformerField)
$if(%_temp_ordered_currentCustomPerformerValues%,$unset(%_temp_ordered_currentCustomPerformerValues%))
$noop(keep list of instruments so the tags can be scripted)
$copymerge(_standardizedInstruments,_standardizedInstrument)
)
)
$set(_skipInstrument,)
)$noop(Close foreach _instruments)
$noop(Delete temporary fields that leaked out from internal variables)
$foreach(%_temporaryPerformerFields%,
$delete(%_loop_value%)
)
$noop(
$if(%_temporaryPerformerFields%,$delete(_temporaryPerformerFields))
)
$noop(Delete any local performer fields that the server doesn't know about following name standardization)
$foreach($unique($get(%_instrumentsFieldName%)),
$set(_currentCustomPerformerField,performer %_loop_value%)
$noop(Picard is case sensitive, so MP3 TXXX tags must be manually handled - Picard apparently reads ALLCAPS m4a tags as lower case...)
$if($eq_any($upper(%_extension%),MP3),$set(_currentCustomPerformerField,$upper(%_currentCustomPerformerField%)))
$if($find(%_standardizedInstruments%,%_loop_value%),,$delete(%_currentCustomPerformerField%))
)
$noop(Save instruments, removing any local instruments that MusicBrainz doesn't know about)
$delete(%_instrumentsFieldName%)
$foreach($unique(%_standardizedInstruments%),
$set(_standardizedInstrument,%_loop_value%)
$copymerge(%_instrumentsFieldName%,_standardizedInstrument)
$noop(Flatten M4A performer tags: Mutagen writes multi-value tags that can't be read correctly by foobar2000, Mp3tag, etc.)
$if($eq($upper(%_extension%),M4A),
$noop(Set custom field's name)
$set(_currentCustomPerformerField,performer %_standardizedInstrument%)
$set(%_currentCustomPerformerField%,$join($get(%_currentCustomPerformerField%),; ))
)
)
$noop(Flatten M4A instruments tag: Mutagen writes multi-value tags that can't be read correctly by foobar2000, Mp3tag, etc.)
$if($eq($upper(%_extension%),M4A),
$if($gt($lenmulti(%instruments%),0),
$set(count_instruments,$lenmulti(%instruments%))
)
$set(instruments,$join(%instruments%,; ))
)
$unset(performer:*)
$noop(I like to indicate whether these are track-level, release-level, or 'reduction by ear' credits. You need to manually fill this in.)
$set(_instruments_precision,$get(%_instrumentsPrecisionField%))
$if($and($gt($lenmulti(%_instruments%),0),$eq(0,$len(%_instruments_precision%))),
$set(%_instrumentsPrecisionField%,?)
)