<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta content="MSHTML 6.00.6000.17102" name="GENERATOR">
</head>
<body>
<div dir="ltr" align="left"><font face="Arial" color="#0000ff" size="2"><span class="752170214-06102011">Attached is the patch of the change to
<strong>mpegfile.cpp </strong>for improved validity detection of mp3 files.</span></font></div>
<div dir="ltr" align="left"><font face="Arial" color="#0000ff" size="2"><span class="752170214-06102011"></span></font> </div>
<div dir="ltr" align="left"><font face="Arial" color="#0000ff" size="2"><span class="752170214-06102011">Regards,</span></font></div>
<div dir="ltr" align="left"><font face="Arial" color="#0000ff" size="2"><span class="752170214-06102011">David Place</span></font></div>
<br>
<div class="OutlookMessageHeader" lang="en-us" dir="ltr" align="left">
<hr tabindex="-1">
<font face="Tahoma" size="2"><b>From:</b> David Place <br>
<b>Sent:</b> 05 September 2011 10:43<br>
<b>To:</b> taglib-devel@kde.org<br>
<b>Subject:</b> RE: Detection of valid audio files<br>
</font><br>
</div>
<div></div>
<div dir="ltr" align="left"><span class="140023509-05092011"><font face="Arial" color="#0000ff" size="2">Hi all. I'm picking up this old thread I started a while ago because I've now done some more changes.</font></span></div>
<div dir="ltr" align="left"><span class="140023509-05092011"><font face="Arial" color="#0000ff" size="2">Since then we've discovered some MP3 files were detected as invalid after my previous patch.</font></span></div>
<div dir="ltr" align="left"><span class="140023509-05092011"><font face="Arial" color="#0000ff" size="2">This was because the MP3 files were inside a WAV container and didn't contain any tags. These additional changes fix that:</font></span></div>
<div dir="ltr" align="left"><span class="140023509-05092011"><font face="Arial" color="#0000ff" size="2"></font></span> </div>
<div dir="ltr" align="left"><span class="140023509-05092011">
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-spacerun: yes"> 
</span></span><span style="FONT-SIZE: 10pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">//if no tag was found at all, make sure this is a valid MP3 file by checking the MP3 header</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-spacerun: yes"> 
</span></span><b><span style="FONT-SIZE: 10pt; COLOR: #7f0055; FONT-FAMILY: 'Courier New'">if</span></b><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"> (!d->hasID3v2 && ! d->hasID3v1 && !d->hasAPE) {</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 1">     
</span></span><span style="FONT-SIZE: 10pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">//goto the beginning of the file and read the header</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 1">     
</span>seek(0);</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 1">     
</span>MPEG::Header header(readBlock(4));</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 1">     
</span></span><b><span style="FONT-SIZE: 10pt; COLOR: #7f0055; FONT-FAMILY: 'Courier New'">bool</span></b><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"> valid = header.isValid();</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p> </o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 1">     
</span></span><span style="FONT-SIZE: 10pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">//if still not valid then maybe the MP3 stream is in a WAV container?...</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 1">     
</span></span><b><span style="FONT-SIZE: 10pt; COLOR: #7f0055; FONT-FAMILY: 'Courier New'">if</span></b><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"> (!valid) {</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 2">           
</span>RIFF::WAV::File* wav = </span><b><span style="FONT-SIZE: 10pt; COLOR: #7f0055; FONT-FAMILY: 'Courier New'">new</span></b><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"> RIFF::WAV::File(name(), readProperties, propertiesStyle);</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 2">           
</span>valid = wav->isValid();</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p> </o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 2">           
</span></span><span style="FONT-SIZE: 10pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">//now test to make sure this isn't a WAV file renamed to MP3...</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 2">           
</span></span><b><span style="FONT-SIZE: 10pt; COLOR: #7f0055; FONT-FAMILY: 'Courier New'">if</span></b><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"> (valid) {</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 3">                 
</span></span><span style="FONT-SIZE: 10pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">//current position will be the beginning of the "data" chunk</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 3">                 
</span></span><b><span style="FONT-SIZE: 10pt; COLOR: #7f0055; FONT-FAMILY: 'Courier New'">long</span></b><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"> pos = wav->tell();</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p> </o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 3">                 
</span></span><span style="FONT-SIZE: 10pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">//we need to seek over the chunk id ("data") and the chunk size (4 bytes)</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 3">                 
</span>wav->seek(pos + 8);</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 3">                 
</span>MPEG::Header header(wav->readBlock(4));</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 3">                 
</span>valid = header.isValid();</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 2">           
</span>}</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p> </o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 2">           
</span></span><b><span style="FONT-SIZE: 10pt; COLOR: #7f0055; FONT-FAMILY: 'Courier New'">delete</span></b><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"> wav;</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 1">     
</span>}</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p> </o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-tab-count: 1">     
</span>setValid(valid);</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span style="mso-spacerun: yes"> 
</span>}</span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"></span> </p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span class="140023509-05092011"><font face="Arial" color="#0000ff">Does anyone know a better way of handling MP3 validity?</font></span></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span class="140023509-05092011"></span></span> </p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span class="140023509-05092011"><font face="Arial" color="#0000ff">Regards,</font></span></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt"><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"><span class="140023509-05092011"><font face="Arial" color="#0000ff">David</font></span></span><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"></span></p>
</span></div>
<br>
<div class="OutlookMessageHeader" lang="en-us" dir="ltr" align="left">
<hr tabindex="-1">
<font face="Tahoma" size="2"><b>From:</b> David Place [mailto:David.Place@tomtom.com]
<br>
<b>Sent:</b> 03 June 2011 17:19<br>
<b>To:</b> taglib-devel@kde.org<br>
<b>Subject:</b> Detection of valid audio files<br>
</font><br>
</div>
<div></div>
<div><span class="763415815-03062011"><font face="Arial" size="2">Hi, one of the requirements we have here is to detect if an audio file is valid or not. E.g: if an EXE file was renamed to .MP3, we need to know that it's bad! I've tested this on several of
 the supported file formats and the behaviour of TagLib seems to vary. Sometimes FileRef.IsNull() is true, sometimes I have to check the Tag() pointer and even sometimes I need to check the audioProperties() pointer. However, with MP3 files, the results from
 a valid MP3 file without any tags (ID3v1, ID3v2 & APE) and an invalid MP3 file are the same so I can't detect if it's truely a valid MP3 file or not. Even the audioProperties() gives me results.</font></span></div>
<div><span class="763415815-03062011"><font face="Arial" size="2"></font></span> </div>
<div><span class="763415815-03062011"><font face="Arial" size="2">I have found a way around this by a small modification to 'mpegfile.cpp' in MPEG::File::read:</font></span></div>
<div><span class="763415815-03062011"><font face="Arial" size="2"></font><font face="Arial" size="2"></font></span> </div>
<div><span class="763415815-03062011">
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-bidi-font-family: Consolas"><span style="mso-spacerun: yes"> 
</span><span style="COLOR: green">//if no tag was found at all, make sure this is a valid MP3 file by checking the MP3 header</span><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-bidi-font-family: Consolas"><span style="mso-spacerun: yes"> 
</span><span style="COLOR: blue">if</span> (!d->hasID3v2 && ! d->hasID3v1 && !d->hasAPE) {<o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-bidi-font-family: Consolas"><span style="mso-tab-count: 1">      
</span><span style="COLOR: green">//goto the beginning of the file and read the header</span><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-bidi-font-family: Consolas"><span style="mso-tab-count: 1">      
</span>seek(0);<o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-bidi-font-family: Consolas"><span style="mso-tab-count: 1">      
</span>MPEG::Header header(readBlock(4));<o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-bidi-font-family: Consolas"><span style="mso-tab-count: 1">      
</span>setValid(header.isValid());<o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><span style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-bidi-font-family: Consolas"><span style="mso-spacerun: yes"> 
</span>}<o:p></o:p></span></p>
</span></div>
<div><span class="763415815-03062011"><font face="Arial" size="2"></font></span> </div>
<div><span class="763415815-03062011"><font face="Arial" size="2">So after the tags have tried to be read, if no tags could be read, check the MPEG header. This seems ok to me providing the first 4 bytes of the file would ALWAYS be the start of an MPEG header
 for valid MP3 file.</font></span></div>
<div><span class="763415815-03062011"><font face="Arial" size="2"></font></span> </div>
<div><span class="763415815-03062011"><font face="Arial" size="2">Is this approach any good?</font></span></div>
<div><span class="763415815-03062011"><font face="Arial" size="2"></font></span> </div>
<div><span class="763415815-03062011"><font face="Arial" size="2">Thanks,</font></span></div>
<div><span class="763415815-03062011"><font face="Arial" size="2">David</font></span></div>
<div><span class="763415815-03062011"><font face="Arial" size="2"></font></span> </div>
</body>
</html>