1 package org.farng.mp3; 2 3 import org.farng.mp3.id3.AbstractID3v2FrameBody; 4 import org.farng.mp3.id3.FrameBodyCOMM; 5 import org.farng.mp3.id3.FrameBodyTIPL; 6 7 import java.util.HashMap; 8 import java.util.Iterator; 9 import java.util.LinkedList; 10 import java.util.List; 11 import java.util.Map; 12 13 /** 14 * Options that are used for every object and class in this library. 15 * 16 * @author Eric Farng 17 * @version $Revision: 1.3 $ 18 */ 19 public class TagOptionSingleton { 20 21 private static final Map tagOptionTable = new HashMap(); 22 private static final String DEFAULT = "default"; 23 private static Object defaultOptions = TagOptionSingleton.DEFAULT; 24 private Map keywordMap = new HashMap(); 25 /** 26 * Map of lyric ID's to Boolean objects if we should or should not save the specific Kyrics3 field. Defaults to 27 * true. 28 */ 29 private Map lyrics3SaveFieldMap = new HashMap(); 30 /** 31 * parenthesis map stuff 32 */ 33 private Map parenthesisMap = new HashMap(); 34 /** 35 * <code>HashMap</code> listing words to be replaced if found 36 */ 37 private Map replaceWordMap = new HashMap(); 38 private List endWordDelimiterList = new LinkedList(); 39 /** 40 * delimiters within a file name 41 */ 42 private List filenameDelimiterList = new LinkedList(); 43 private List startWordDelimiterList = new LinkedList(); 44 /** 45 * words to always set the case as upper or lower case 46 */ 47 private List upperLowerCaseWordList = new LinkedList(); 48 /** 49 * default language for any ID3v2 tags frameswhich require it. This string is in the [ISO-639-2] ISO/FDIS 639-2 50 * definition 51 */ 52 private String language = "eng"; 53 private boolean compositeMatchOverwrite = false; 54 private boolean filenameTagSave = false; 55 /** 56 * if we should save any fields of the ID3v1 tag or not. Defaults to true. 57 */ 58 private boolean id3v1Save = true; 59 /** 60 * if we should save the album field of the ID3v1 tag or not. Defaults to true. 61 */ 62 private boolean id3v1SaveAlbum = true; 63 /** 64 * if we should save the artist field of the ID3v1 tag or not. Defaults to true. 65 */ 66 private boolean id3v1SaveArtist = true; 67 /** 68 * if we should save the comment field of the ID3v1 tag or not. Defaults to true. 69 */ 70 private boolean id3v1SaveComment = true; 71 /** 72 * if we should save the genre field of the ID3v1 tag or not. Defaults to true. 73 */ 74 private boolean id3v1SaveGenre = true; 75 /** 76 * if we should save the title field of the ID3v1 tag or not. Defaults to true. 77 */ 78 private boolean id3v1SaveTitle = true; 79 /** 80 * if we should save the track field of the ID3v1 tag or not. Defaults to true. 81 */ 82 private boolean id3v1SaveTrack = true; 83 /** 84 * if we should save the year field of the ID3v1 tag or not. Defaults to true. 85 */ 86 private boolean id3v1SaveYear = true; 87 /** 88 * if we should keep an empty ID3v2 frame while we're reading. This is different from a string of white space. 89 * Defaults to false. 90 */ 91 //todo I don't think I'm checking this right now 92 private boolean id3v2KeepEmptyFrameIfRead = false; 93 /** 94 * When adjusting the ID3v2 padding, if should we copy the current ID3v2 tag to the new MP3 file. Defaults to true. 95 */ 96 private boolean id3v2PaddingCopyTag = true; 97 /** 98 * When adjusting the ID3v2 padding, if we should shorten the length of the ID3v2 tag padding. Defaults to false. 99 */ 100 private boolean id3v2PaddingWillShorten = false; 101 /** 102 * if we should save any fields of the ID3v2 tag or not. Defaults to true. 103 */ 104 private boolean id3v2Save = true; 105 /** 106 * if we should save empty ID3v2 frames or not. Defaults to false. 107 */ 108 //todo I don't think this is implemented yet. 109 private boolean id3v2SaveEmptyFrame = false; 110 /** 111 * if we should save the ID3v2 extended header or not. Defaults to false. 112 */ 113 //todo Not implemented yet 114 private boolean id3v2SaveExtendedHeader = false; 115 /** 116 * if we should keep an empty Lyrics3 field while we're reading. This is different from a string of white space. 117 * Defaults to false. 118 */ 119 private boolean lyrics3KeepEmptyFieldIfRead = false; 120 /** 121 * if we should save any fields of the Lyrics3 tag or not. Defaults to true. 122 */ 123 private boolean lyrics3Save = true; 124 /** 125 * if we should save empty Lyrics3 field or not. Defaults to false. 126 */ 127 //todo I don't think this is implemented yet. 128 private boolean lyrics3SaveEmptyField = false; 129 private boolean originalSavedAfterAdjustingID3v2Padding = true; 130 /** 131 * default play counter size in bytes for the ID3v2 Tag. 132 */ 133 //todo implement this. 134 private byte playCounterSize = 4; 135 /** 136 * default text encoding for any ID3v2 tag frames which require it. 137 */ 138 private byte textEncoding = 0; 139 /** 140 * default time stamp format for any ID3v2 tag frames which require it. 141 */ 142 private byte timeStampFormat = 2; 143 /** 144 * factor to increase the id3v2 padding size. When the ID3v2 tag padding length is calculated and is not large 145 * enough to fit the current ID3v2 tag, the padding length will be multiplied by this number until it is large 146 * enough. 147 */ 148 private float id3v2PaddingMultiplier = 2; 149 private int defaultSaveMode = TagConstant.MP3_FILE_SAVE_WRITE; 150 /** 151 * padding length of the ID3v2 tag. 152 */ 153 private int id3v2PaddingSize = 2048; 154 /** 155 * number of frames to sync when trying to find the start of the MP3 frame data. The start of the MP3 frame data is 156 * the start of the music and is different from the ID3v2 frame data. 157 */ 158 private int numberMP3SyncFrame = 5; 159 160 /** 161 * Creates a new TagOptions object. All Options are set to their default values 162 */ TagOptionSingleton()163 private TagOptionSingleton() { 164 setToDefault(); 165 } 166 getInstance()167 public static TagOptionSingleton getInstance() { 168 return getInstance(defaultOptions); 169 } 170 getInstance(final Object instanceKey)171 public static TagOptionSingleton getInstance(final Object instanceKey) { 172 TagOptionSingleton tagOptions = (TagOptionSingleton) tagOptionTable.get(instanceKey); 173 if (tagOptions == null) { 174 tagOptions = new TagOptionSingleton(); 175 tagOptionTable.put(instanceKey, tagOptions); 176 } 177 return tagOptions; 178 } 179 getCloseParenthesis(final String open)180 public String getCloseParenthesis(final String open) { 181 return (String) parenthesisMap.get(open); 182 } 183 isCloseParenthesis(final String close)184 public boolean isCloseParenthesis(final String close) { 185 return parenthesisMap.containsValue(close); 186 } 187 setCompositeMatchOverwrite(final boolean compositeMatchOverwrite)188 public void setCompositeMatchOverwrite(final boolean compositeMatchOverwrite) { 189 this.compositeMatchOverwrite = compositeMatchOverwrite; 190 } 191 isCompositeMatchOverwrite()192 public boolean isCompositeMatchOverwrite() { 193 return compositeMatchOverwrite; 194 } 195 setDefaultSaveMode(final int defaultSaveMode)196 public void setDefaultSaveMode(final int defaultSaveMode) { 197 this.defaultSaveMode = defaultSaveMode; 198 } 199 getDefaultSaveMode()200 public int getDefaultSaveMode() { 201 return this.defaultSaveMode; 202 } 203 setFilenameTagSave(final boolean filenameTagSave)204 public void setFilenameTagSave(final boolean filenameTagSave) { 205 this.filenameTagSave = filenameTagSave; 206 } 207 isFilenameTagSave()208 public boolean isFilenameTagSave() { 209 return this.filenameTagSave; 210 } 211 isId3v2SaveExtendedHeader()212 public boolean isId3v2SaveExtendedHeader() { 213 return this.id3v2SaveExtendedHeader; 214 } 215 setInstanceKey(final Object instanceKey)216 public void setInstanceKey(final Object instanceKey) { 217 TagOptionSingleton.defaultOptions = instanceKey; 218 } 219 getInstanceKey()220 public static Object getInstanceKey() { 221 return defaultOptions; 222 } 223 getEndWordDelimiterIterator()224 public Iterator getEndWordDelimiterIterator() { 225 return this.endWordDelimiterList.iterator(); 226 } 227 getFilenameDelimiterIterator()228 public Iterator getFilenameDelimiterIterator() { 229 return this.filenameDelimiterList.iterator(); 230 } 231 setId3v1Save(final boolean id3v1Save)232 public void setId3v1Save(final boolean id3v1Save) { 233 this.id3v1Save = id3v1Save; 234 } 235 isId3v1Save()236 public boolean isId3v1Save() { 237 return this.id3v1Save; 238 } 239 setId3v1SaveAlbum(final boolean id3v1SaveAlbum)240 public void setId3v1SaveAlbum(final boolean id3v1SaveAlbum) { 241 this.id3v1SaveAlbum = id3v1SaveAlbum; 242 } 243 isId3v1SaveAlbum()244 public boolean isId3v1SaveAlbum() { 245 return this.id3v1SaveAlbum; 246 } 247 setId3v1SaveArtist(final boolean id3v1SaveArtist)248 public void setId3v1SaveArtist(final boolean id3v1SaveArtist) { 249 this.id3v1SaveArtist = id3v1SaveArtist; 250 } 251 isId3v1SaveArtist()252 public boolean isId3v1SaveArtist() { 253 return this.id3v1SaveArtist; 254 } 255 setId3v1SaveComment(final boolean id3v1SaveComment)256 public void setId3v1SaveComment(final boolean id3v1SaveComment) { 257 this.id3v1SaveComment = id3v1SaveComment; 258 } 259 isId3v1SaveComment()260 public boolean isId3v1SaveComment() { 261 return this.id3v1SaveComment; 262 } 263 setId3v1SaveGenre(final boolean id3v1SaveGenre)264 public void setId3v1SaveGenre(final boolean id3v1SaveGenre) { 265 this.id3v1SaveGenre = id3v1SaveGenre; 266 } 267 isId3v1SaveGenre()268 public boolean isId3v1SaveGenre() { 269 return this.id3v1SaveGenre; 270 } 271 setId3v1SaveTitle(final boolean id3v1SaveTitle)272 public void setId3v1SaveTitle(final boolean id3v1SaveTitle) { 273 this.id3v1SaveTitle = id3v1SaveTitle; 274 } 275 isId3v1SaveTitle()276 public boolean isId3v1SaveTitle() { 277 return this.id3v1SaveTitle; 278 } 279 setId3v1SaveTrack(final boolean id3v1SaveTrack)280 public void setId3v1SaveTrack(final boolean id3v1SaveTrack) { 281 this.id3v1SaveTrack = id3v1SaveTrack; 282 } 283 isId3v1SaveTrack()284 public boolean isId3v1SaveTrack() { 285 return this.id3v1SaveTrack; 286 } 287 setId3v1SaveYear(final boolean id3v1SaveYear)288 public void setId3v1SaveYear(final boolean id3v1SaveYear) { 289 this.id3v1SaveYear = id3v1SaveYear; 290 } 291 isId3v1SaveYear()292 public boolean isId3v1SaveYear() { 293 return this.id3v1SaveYear; 294 } 295 setId3v2KeepEmptyFrameIfRead(final boolean id3v2KeepEmptyFrameIfRead)296 public void setId3v2KeepEmptyFrameIfRead(final boolean id3v2KeepEmptyFrameIfRead) { 297 this.id3v2KeepEmptyFrameIfRead = id3v2KeepEmptyFrameIfRead; 298 } 299 isId3v2KeepEmptyFrameIfRead()300 public boolean isId3v2KeepEmptyFrameIfRead() { 301 return this.id3v2KeepEmptyFrameIfRead; 302 } 303 setId3v2PaddingCopyTag(final boolean id3v2PaddingCopyTag)304 public void setId3v2PaddingCopyTag(final boolean id3v2PaddingCopyTag) { 305 this.id3v2PaddingCopyTag = id3v2PaddingCopyTag; 306 } 307 isId3v2PaddingCopyTag()308 public boolean isId3v2PaddingCopyTag() { 309 return this.id3v2PaddingCopyTag; 310 } 311 312 /** 313 * Sets the factor to increase the id3v2 padding size. When the ID3v2 tag padding length is calculated and is not 314 * large enough to fit the current ID3v2 tag, the padding length will be multiplied by this number until it is large 315 * enough. 316 * 317 * @param mult new factor to increase the id3v2 padding size. 318 */ setId3v2PaddingMultiplier(final float mult)319 public void setId3v2PaddingMultiplier(final float mult) { 320 if (mult > 1) { 321 this.id3v2PaddingMultiplier = mult; 322 } 323 } 324 325 /** 326 * Returns the factor to increase the id3v2 padding size. When the ID3v2 tag padding length is calculated and is not 327 * large enough to fit the current ID3v2 tag, the padding length will be multiplied by this number until it is large 328 * enough. 329 * 330 * @return the factor to increase the id3v2 padding size 331 */ getId3v2PaddingMultiplier()332 public float getId3v2PaddingMultiplier() { 333 return this.id3v2PaddingMultiplier; 334 } 335 336 /** 337 * Sets the initial ID3v2 padding length. This will be the minimum padding length of the ID3v2 tag. The 338 * <code>willShorten</code> setting will not make the length shorter than this value. 339 * 340 * @param size the new initial ID3v2 padding length 341 */ setId3v2PaddingSize(final int size)342 public void setId3v2PaddingSize(final int size) { 343 if (size >= 0) { 344 this.id3v2PaddingSize = size; 345 } 346 } 347 348 /** 349 * Returns the initial ID3v2 padding length. This will be the minimum padding length of the ID3v2 tag. The 350 * <code>willShorten</code> setting will not make the length shorter than this value. 351 * 352 * @return the initial ID3v2 padding length 353 */ getId3v2PaddingSize()354 public int getId3v2PaddingSize() { 355 return this.id3v2PaddingSize; 356 } 357 setId3v2PaddingWillShorten(final boolean id3v2PaddingWillShorten)358 public void setId3v2PaddingWillShorten(final boolean id3v2PaddingWillShorten) { 359 this.id3v2PaddingWillShorten = id3v2PaddingWillShorten; 360 } 361 isId3v2PaddingWillShorten()362 public boolean isId3v2PaddingWillShorten() { 363 return this.id3v2PaddingWillShorten; 364 } 365 setId3v2Save(final boolean id3v2Save)366 public void setId3v2Save(final boolean id3v2Save) { 367 this.id3v2Save = id3v2Save; 368 } 369 isId3v2Save()370 public boolean isId3v2Save() { 371 return this.id3v2Save; 372 } 373 setId3v2SaveEmptyFrame(final boolean id3v2SaveEmptyFrame)374 public void setId3v2SaveEmptyFrame(final boolean id3v2SaveEmptyFrame) { 375 this.id3v2SaveEmptyFrame = id3v2SaveEmptyFrame; 376 } 377 isId3v2SaveEmptyFrame()378 public boolean isId3v2SaveEmptyFrame() { 379 return this.id3v2SaveEmptyFrame; 380 } 381 setId3v2SaveExtendedHeader(final boolean id3v2SaveExtendedHeader)382 public void setId3v2SaveExtendedHeader(final boolean id3v2SaveExtendedHeader) { 383 this.id3v2SaveExtendedHeader = id3v2SaveExtendedHeader; 384 } 385 getKeywordIterator()386 public Iterator getKeywordIterator() { 387 return this.keywordMap.keySet().iterator(); 388 } 389 getKeywordListIterator(final Class id3v2_4FrameBody)390 public Iterator getKeywordListIterator(final Class id3v2_4FrameBody) { 391 return ((LinkedList) this.keywordMap.get(id3v2_4FrameBody)).iterator(); 392 } 393 394 /** 395 * Sets the default language for any ID3v2 tag frames which require it. While the value will already exist when 396 * reading from a file, this value will be used when a new ID3v2 Frame is created from scratch. 397 * 398 * @param language language ID, [ISO-639-2] ISO/FDIS 639-2 definition 399 */ setLanguage(final String language)400 public void setLanguage(final String language) { 401 if (TagConstant.languageIdToString.containsKey(language)) { 402 this.language = language; 403 } 404 } 405 406 /** 407 * Returns the default language for any ID3v2 tag frames which require it. 408 * 409 * @return language ID, [ISO-639-2] ISO/FDIS 639-2 definition 410 */ getLanguage()411 public String getLanguage() { 412 return this.language; 413 } 414 setLyrics3KeepEmptyFieldIfRead(final boolean lyrics3KeepEmptyFieldIfRead)415 public void setLyrics3KeepEmptyFieldIfRead(final boolean lyrics3KeepEmptyFieldIfRead) { 416 this.lyrics3KeepEmptyFieldIfRead = lyrics3KeepEmptyFieldIfRead; 417 } 418 isLyrics3KeepEmptyFieldIfRead()419 public boolean isLyrics3KeepEmptyFieldIfRead() { 420 return this.lyrics3KeepEmptyFieldIfRead; 421 } 422 setLyrics3Save(final boolean lyrics3Save)423 public void setLyrics3Save(final boolean lyrics3Save) { 424 this.lyrics3Save = lyrics3Save; 425 } 426 isLyrics3Save()427 public boolean isLyrics3Save() { 428 return this.lyrics3Save; 429 } 430 setLyrics3SaveEmptyField(final boolean lyrics3SaveEmptyField)431 public void setLyrics3SaveEmptyField(final boolean lyrics3SaveEmptyField) { 432 this.lyrics3SaveEmptyField = lyrics3SaveEmptyField; 433 } 434 isLyrics3SaveEmptyField()435 public boolean isLyrics3SaveEmptyField() { 436 return this.lyrics3SaveEmptyField; 437 } 438 439 /** 440 * Sets if we should save the Lyrics3 field. Defaults to true. 441 * 442 * @param id Lyrics3 id string 443 * @param save true if you want to save this specific Lyrics3 field. 444 */ setLyrics3SaveField(final String id, final boolean save)445 public void setLyrics3SaveField(final String id, final boolean save) { 446 this.lyrics3SaveFieldMap.put(id, new Boolean(save)); 447 } 448 449 /** 450 * Returns true if we should save the Lyrics3 field asked for in the argument. Defaults to true. 451 * 452 * @param id Lyrics3 id string 453 * 454 * @return true if we should save the Lyrics3 field. 455 */ getLyrics3SaveField(final String id)456 public boolean getLyrics3SaveField(final String id) { 457 return ((Boolean) this.lyrics3SaveFieldMap.get(id)).booleanValue(); 458 } 459 getLyrics3SaveFieldMap()460 public Map getLyrics3SaveFieldMap() { 461 return this.lyrics3SaveFieldMap; 462 } 463 getNewReplaceWord(final String oldWord)464 public String getNewReplaceWord(final String oldWord) { 465 return (String) this.replaceWordMap.get(oldWord); 466 } 467 468 /** 469 * Sets the number of MP3 frames to sync when trying to find the start of the MP3 frame data. The start of the MP3 470 * frame data is the start of the music and is different from the ID3v2 frame data. WinAmp 2.8 seems to sync 3 471 * frames. Default is 5. 472 * 473 * @param numberMP3SyncFrame number of MP3 frames to sync 474 */ setNumberMP3SyncFrame(final int numberMP3SyncFrame)475 public void setNumberMP3SyncFrame(final int numberMP3SyncFrame) { 476 this.numberMP3SyncFrame = numberMP3SyncFrame; 477 } 478 479 /** 480 * Returns the number of MP3 frames to sync when trying to find the start of the MP3 frame data. The start of the 481 * MP3 frame data is the start of the music and is different from the ID3v2 frame data. WinAmp 2.8 seems to sync 3 482 * frames. Default is 5. 483 * 484 * @return number of MP3 frames to sync 485 */ getNumberMP3SyncFrame()486 public int getNumberMP3SyncFrame() { 487 return this.numberMP3SyncFrame; 488 } 489 getOldReplaceWordIterator()490 public Iterator getOldReplaceWordIterator() { 491 return this.replaceWordMap.keySet().iterator(); 492 } 493 isOpenParenthesis(final String open)494 public boolean isOpenParenthesis(final String open) { 495 return this.parenthesisMap.containsKey(open); 496 } 497 getOpenParenthesisIterator()498 public Iterator getOpenParenthesisIterator() { 499 return this.parenthesisMap.keySet().iterator(); 500 } 501 setOriginalSavedAfterAdjustingID3v2Padding(final boolean originalSavedAfterAdjustingID3v2Padding)502 public void setOriginalSavedAfterAdjustingID3v2Padding(final boolean originalSavedAfterAdjustingID3v2Padding) { 503 this.originalSavedAfterAdjustingID3v2Padding = originalSavedAfterAdjustingID3v2Padding; 504 } 505 isOriginalSavedAfterAdjustingID3v2Padding()506 public boolean isOriginalSavedAfterAdjustingID3v2Padding() { 507 return this.originalSavedAfterAdjustingID3v2Padding; 508 } 509 510 /** 511 * Sets the default play counter size for the PCNT ID3v2 frame. While the value will already exist when reading from 512 * a file, this value will be used when a new ID3v2 Frame is created from scratch. 513 * 514 * @param size the default play counter size for the PCNT ID3v2 frame 515 */ setPlayCounterSize(final byte size)516 public void setPlayCounterSize(final byte size) { 517 if (size > 0) { 518 this.playCounterSize = size; 519 } 520 } 521 522 /** 523 * Returns the default play counter size for the PCNT ID3v2 frame. 524 * 525 * @return the default play counter size for the PCNT ID3v2 frame 526 */ getPlayCounterSize()527 public byte getPlayCounterSize() { 528 return this.playCounterSize; 529 } 530 getStartWordDelimiterIterator()531 public Iterator getStartWordDelimiterIterator() { 532 return this.startWordDelimiterList.iterator(); 533 } 534 535 /** 536 * Sets the default text encoding for any ID3v2 tag frames which require it. While the value will already exist when 537 * reading from a file, this value will be used when a new ID3v2 Frame is created from scratch. 538 * <p/> 539 * <P> $00 ISO-8859-1 [ISO-8859-1]. Terminated with $00. <BR> $01 UTF-16 [UTF-16] encoded Unicode [UNICODE] with 540 * BOM. All strings in the same frame SHALL have the same byteorder. Terminated with $00 00. <BR> $02 UTF-16BE 541 * [UTF-16] encoded Unicode [UNICODE] without BOM. Terminated with $00 00. <BR> $03 UTF-8 [UTF-8] encoded Unicode 542 * [UNICODE]. Terminated with $00. <BR> </p> 543 * 544 * @param enc new default text encoding 545 */ setTextEncoding(final byte enc)546 public void setTextEncoding(final byte enc) { 547 if ((enc >= 0) && (enc <= 3)) { 548 this.textEncoding = enc; 549 } 550 } 551 552 /** 553 * Returns the default text encoding format for ID3v2 tags which require it. 554 * <p/> 555 * <P> $00 ISO-8859-1 [ISO-8859-1]. Terminated with $00. <BR> $01 UTF-16 [UTF-16] encoded Unicode [UNICODE] with 556 * BOM. All strings in the same frame SHALL have the same byteorder. Terminated with $00 00. <BR> $02 UTF-16BE 557 * [UTF-16] encoded Unicode [UNICODE] without BOM. Terminated with $00 00. <BR> $03 UTF-8 [UTF-8] encoded Unicode 558 * [UNICODE]. Terminated with $00. <BR> </p> 559 * 560 * @return the default text encoding 561 */ getTextEncoding()562 public byte getTextEncoding() { 563 return this.textEncoding; 564 } 565 566 /** 567 * Sets the default time stamp format for ID3v2 tags which require it. While the value will already exist when 568 * reading from a file, this value will be used when a new ID3v2 Frame is created from scratch. 569 * <p/> 570 * <P> $01 Absolute time, 32 bit sized, using MPEG frames as unit <br> $02 Absolute time, 32 bit sized, using 571 * milliseconds as unit <br> </p> 572 * 573 * @param tsf the new default time stamp format 574 */ setTimeStampFormat(final byte tsf)575 public void setTimeStampFormat(final byte tsf) { 576 if ((tsf == 1) || (tsf == 2)) { 577 this.timeStampFormat = tsf; 578 } 579 } 580 581 /** 582 * Returns the default time stamp format for ID3v2 tags which require it. 583 * <p/> 584 * <P> $01 Absolute time, 32 bit sized, using MPEG frames as unit <br> $02 Absolute time, 32 bit sized, using 585 * milliseconds as unit <br> </p> 586 * 587 * @return the default time stamp format 588 */ getTimeStampFormat()589 public byte getTimeStampFormat() { 590 return this.timeStampFormat; 591 } 592 setToDefault()593 public void setToDefault() { 594 this.keywordMap = new HashMap(); 595 this.compositeMatchOverwrite = false; 596 this.defaultSaveMode = TagConstant.MP3_FILE_SAVE_WRITE; 597 this.endWordDelimiterList = new LinkedList(); 598 this.filenameDelimiterList = new LinkedList(); 599 this.filenameTagSave = false; 600 this.id3v1Save = true; 601 this.id3v1SaveAlbum = true; 602 this.id3v1SaveArtist = true; 603 this.id3v1SaveComment = true; 604 this.id3v1SaveGenre = true; 605 this.id3v1SaveTitle = true; 606 this.id3v1SaveTrack = true; 607 this.id3v1SaveYear = true; 608 this.id3v2KeepEmptyFrameIfRead = false; 609 this.id3v2PaddingCopyTag = true; 610 this.id3v2PaddingWillShorten = false; 611 this.id3v2Save = true; 612 this.id3v2SaveEmptyFrame = false; 613 this.id3v2SaveExtendedHeader = false; 614 this.id3v2PaddingMultiplier = 2; 615 this.id3v2PaddingSize = 2048; 616 this.language = "eng"; 617 this.lyrics3KeepEmptyFieldIfRead = false; 618 this.lyrics3Save = true; 619 this.lyrics3SaveEmptyField = false; 620 this.lyrics3SaveFieldMap = new HashMap(); 621 this.numberMP3SyncFrame = 5; 622 this.parenthesisMap = new HashMap(); 623 this.playCounterSize = 4; 624 this.replaceWordMap = new HashMap(); 625 this.startWordDelimiterList = new LinkedList(); 626 this.textEncoding = 0; 627 this.timeStampFormat = 2; 628 this.upperLowerCaseWordList = new LinkedList(); 629 630 /** 631 * default all lyrics3 fields to save. id3v1 fields are individual 632 * settings. id3v2 fields are always looked at to save. 633 */ 634 Iterator iterator = TagConstant.lyrics3v2FieldIdToString.keySet().iterator(); 635 String fieldId; 636 while (iterator.hasNext()) { 637 fieldId = (String) iterator.next(); 638 this.lyrics3SaveFieldMap.put(fieldId, new Boolean(true)); 639 } 640 try { 641 addKeyword(FrameBodyCOMM.class, "ultimix"); 642 addKeyword(FrameBodyCOMM.class, "dance"); 643 addKeyword(FrameBodyCOMM.class, "mix"); 644 addKeyword(FrameBodyCOMM.class, "remix"); 645 addKeyword(FrameBodyCOMM.class, "rmx"); 646 addKeyword(FrameBodyCOMM.class, "live"); 647 addKeyword(FrameBodyCOMM.class, "cover"); 648 addKeyword(FrameBodyCOMM.class, "soundtrack"); 649 addKeyword(FrameBodyCOMM.class, "version"); 650 addKeyword(FrameBodyCOMM.class, "acoustic"); 651 addKeyword(FrameBodyCOMM.class, "original"); 652 addKeyword(FrameBodyCOMM.class, "cd"); 653 addKeyword(FrameBodyCOMM.class, "extended"); 654 addKeyword(FrameBodyCOMM.class, "vocal"); 655 addKeyword(FrameBodyCOMM.class, "unplugged"); 656 addKeyword(FrameBodyCOMM.class, "acapella"); 657 addKeyword(FrameBodyCOMM.class, "edit"); 658 addKeyword(FrameBodyCOMM.class, "radio"); 659 addKeyword(FrameBodyCOMM.class, "original"); 660 addKeyword(FrameBodyCOMM.class, "album"); 661 addKeyword(FrameBodyCOMM.class, "studio"); 662 addKeyword(FrameBodyCOMM.class, "instrumental"); 663 addKeyword(FrameBodyCOMM.class, "unedited"); 664 addKeyword(FrameBodyCOMM.class, "karoke"); 665 addKeyword(FrameBodyCOMM.class, "quality"); 666 addKeyword(FrameBodyCOMM.class, "uncensored"); 667 addKeyword(FrameBodyCOMM.class, "clean"); 668 addKeyword(FrameBodyCOMM.class, "dirty"); 669 addKeyword(FrameBodyTIPL.class, "f."); 670 addKeyword(FrameBodyTIPL.class, "feat"); 671 addKeyword(FrameBodyTIPL.class, "feat."); 672 addKeyword(FrameBodyTIPL.class, "featuring"); 673 addKeyword(FrameBodyTIPL.class, "ftng"); 674 addKeyword(FrameBodyTIPL.class, "ftng."); 675 addKeyword(FrameBodyTIPL.class, "ft."); 676 addKeyword(FrameBodyTIPL.class, "ft"); 677 iterator = TagConstant.genreStringToId.keySet().iterator(); 678 while (iterator.hasNext()) { 679 addKeyword(FrameBodyCOMM.class, (String) iterator.next()); 680 } 681 } catch (TagException ex) { 682 // this shouldn't happen. if it does, we should fix it right away. 683 ex.printStackTrace(); 684 } 685 addUpperLowerCaseWord("a"); 686 addUpperLowerCaseWord("in"); 687 addUpperLowerCaseWord("of"); 688 addUpperLowerCaseWord("the"); 689 addUpperLowerCaseWord("on"); 690 addUpperLowerCaseWord("is"); 691 addUpperLowerCaseWord("it"); 692 addUpperLowerCaseWord("to"); 693 addUpperLowerCaseWord("at"); 694 addUpperLowerCaseWord("an"); 695 addUpperLowerCaseWord("and"); 696 addUpperLowerCaseWord("but"); 697 addUpperLowerCaseWord("or"); 698 addUpperLowerCaseWord("for"); 699 addUpperLowerCaseWord("nor"); 700 addUpperLowerCaseWord("not"); 701 addUpperLowerCaseWord("so"); 702 addUpperLowerCaseWord("yet"); 703 addUpperLowerCaseWord("with"); 704 addUpperLowerCaseWord("into"); 705 addUpperLowerCaseWord("by"); 706 addUpperLowerCaseWord("up"); 707 addUpperLowerCaseWord("as"); 708 addUpperLowerCaseWord("if"); 709 addUpperLowerCaseWord("feat."); 710 addUpperLowerCaseWord("vs."); 711 addUpperLowerCaseWord("I'm"); 712 addUpperLowerCaseWord("I"); 713 addUpperLowerCaseWord("I've"); 714 addUpperLowerCaseWord("I'll"); 715 addReplaceWord("v.", "vs."); 716 addReplaceWord("vs.", "vs."); 717 addReplaceWord("versus", "vs."); 718 addReplaceWord("f.", "feat."); 719 addReplaceWord("feat", "feat."); 720 addReplaceWord("featuring", "feat."); 721 addReplaceWord("ftng.", "feat."); 722 addReplaceWord("ftng", "feat."); 723 addReplaceWord("ft.", "feat."); 724 addReplaceWord("ft", "feat."); 725 addFilenameDelimiter("/"); 726 addFilenameDelimiter("\\"); 727 addFilenameDelimiter(" -"); 728 addFilenameDelimiter(";"); 729 addFilenameDelimiter("|"); 730 addFilenameDelimiter(":"); 731 iterator = this.getKeywordListIterator(FrameBodyTIPL.class); 732 while (iterator.hasNext()) { 733 addStartWordDelimiter((String) iterator.next()); 734 } 735 addParenthesis("(", ")"); 736 addParenthesis("[", "]"); 737 addParenthesis("{", "}"); 738 addParenthesis("<", ">"); 739 } 740 getUpperLowerCaseWordListIterator()741 public Iterator getUpperLowerCaseWordListIterator() { 742 return this.upperLowerCaseWordList.iterator(); 743 } 744 addEndWordDelimiter(final String wordDelimiter)745 public void addEndWordDelimiter(final String wordDelimiter) { 746 this.endWordDelimiterList.add(wordDelimiter); 747 } 748 addFilenameDelimiter(final String delimiter)749 public void addFilenameDelimiter(final String delimiter) { 750 this.filenameDelimiterList.add(delimiter); 751 } 752 addKeyword(final Class id3v2FrameBodyClass, final String keyword)753 public void addKeyword(final Class id3v2FrameBodyClass, final String keyword) throws TagException { 754 if (AbstractID3v2FrameBody.class.isAssignableFrom(id3v2FrameBodyClass) == false) { 755 throw new TagException("Invalid class type. Must be AbstractId3v2FrameBody " + id3v2FrameBodyClass); 756 } 757 if ((keyword != null) && (keyword.length() > 0)) { 758 final LinkedList keywordList; 759 if (this.keywordMap.containsKey(id3v2FrameBodyClass) == false) { 760 keywordList = new LinkedList(); 761 this.keywordMap.put(id3v2FrameBodyClass, keywordList); 762 } else { 763 keywordList = (LinkedList) this.keywordMap.get(id3v2FrameBodyClass); 764 } 765 keywordList.add(keyword); 766 } 767 } 768 addParenthesis(final String open, final String close)769 public void addParenthesis(final String open, final String close) { 770 this.parenthesisMap.put(open, close); 771 } 772 addReplaceWord(final String oldWord, final String newWord)773 public void addReplaceWord(final String oldWord, final String newWord) { 774 this.replaceWordMap.put(oldWord, newWord); 775 } 776 addStartWordDelimiter(final String wordDelimiter)777 public void addStartWordDelimiter(final String wordDelimiter) { 778 this.startWordDelimiterList.add(wordDelimiter); 779 } 780 addUpperLowerCaseWord(final String word)781 public void addUpperLowerCaseWord(final String word) { 782 this.upperLowerCaseWordList.add(word); 783 } 784 }