Changeset 5

Show
Ignore:
Timestamp:
11/08/08 16:03:59 (2 months ago)
Author:
Jeremy
Message:

Implemented tag reading via the Wave INFO chunk

Location:
trunk/AddIns/WaveAudio
Files:
2 added
3 modified
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/AddIns/WaveAudio/RiffReader.cs

    r3 r5  
    1919 
    2020using System; 
     21using System.Collections.Generic; 
    2122using System.IO; 
    2223using System.Text; 
    2324using OmniEncoder.AudioModel.AddInViews; 
    2425 
    25 namespace OmniEncoder.AudioModel.Wave 
     26namespace OmniEncoder.WaveAudio 
    2627{ 
    27     class WaveReader : IDisposable 
     28    class RiffReader : IDisposable 
    2829    { 
    2930        readonly BinaryReader reader; 
     31        readonly Stack<uint> parentChunkLength = new Stack<uint>(2); 
     32        readonly Stack<string> parentChunkType = new Stack<string>(2); 
     33        readonly Stack<uint> parentChunkStart = new Stack<uint>(2); 
    3034 
    31         internal WaveReader(string fileName) 
     35        internal RiffReader(string fileName) 
    3236        { 
    3337            reader = new BinaryReader(File.OpenRead(fileName), Encoding.ASCII); 
    3438 
    35             try 
     39            if (new string(reader.ReadChars(4)) != "RIFF") 
     40                throw new AudioInvalidException("The file '" + fileName + "' does not contain a RIFF header."); 
     41 
     42            parentChunkLength.Push(reader.ReadUInt32() - 4); 
     43            parentChunkType.Push(new string(reader.ReadChars(4))); 
     44            parentChunkStart.Push(12); 
     45        } 
     46 
     47        internal string ChunkType 
     48        { 
     49            get { return parentChunkType.Peek(); } 
     50        } 
     51 
     52        internal bool Descend(string fourCC) 
     53        { 
     54            uint subChunkLength; 
     55            if (AdvanceToChunk(fourCC, out subChunkLength)) 
    3656            { 
    37                 if (new string(reader.ReadChars(4)) != "RIFF") 
    38                     throw new AudioInvalidException("The file '" + fileName + "' does not contain a RIFF header."); 
    39  
    40                 reader.BaseStream.Seek(4, SeekOrigin.Current); 
    41  
    42                 if (new string(reader.ReadChars(4)) != "WAVE") 
    43                     throw new AudioInvalidException("The file '" + fileName + "' is not a Wave file."); 
     57                parentChunkLength.Push(subChunkLength - 4); 
     58                parentChunkType.Push(new string(reader.ReadChars(4))); 
     59                parentChunkStart.Push((uint)reader.BaseStream.Position); 
     60                return true; 
    4461            } 
    45             catch (EndOfStreamException e) 
    46             { 
    47                 throw new AudioInvalidException("The file '" + fileName + "' is missing data.", e); 
    48             } 
     62            else 
     63                return false; 
    4964        } 
    5065 
    5166        internal byte[] ReadChunk(string fourCC) 
    5267        { 
    53             uint chunkSize = ReadChunkSize(fourCC); 
    54             return reader.ReadBytes((int)chunkSize); 
     68            uint chunkLength; 
     69            AdvanceToChunk(fourCC, out chunkLength); 
     70            return reader.ReadBytes((int)chunkLength); 
    5571        } 
    5672 
    57         internal uint ReadChunkSize(string fourCC) 
     73        internal bool AdvanceToChunk(string fourCC, out uint chunkLength) 
    5874        { 
    59             reader.BaseStream.Seek(12, SeekOrigin.Begin); 
     75            reader.BaseStream.Seek(parentChunkStart.Peek(), SeekOrigin.Begin); 
     76 
     77            uint parentChunkEnd = parentChunkStart.Peek() + parentChunkLength.Peek(); 
    6078 
    6179            string currentFourCC = new string(reader.ReadChars(4)); 
    62             uint chunkSize = reader.ReadUInt32(); 
     80            uint currentChunkLength = reader.ReadUInt32(); 
    6381 
    6482            while (currentFourCC != fourCC) 
    6583            { 
    6684                // Chunks are 2-byte aligned. 
    67                 reader.BaseStream.Seek(chunkSize + chunkSize % 2, SeekOrigin.Current); 
     85                reader.BaseStream.Seek(currentChunkLength + currentChunkLength % 2, SeekOrigin.Current); 
     86 
     87                if (reader.BaseStream.Position == parentChunkEnd) 
     88                { 
     89                    chunkLength = 0; 
     90                    return false; 
     91                } 
    6892 
    6993                currentFourCC = new string(reader.ReadChars(4)); 
    70                 chunkSize = reader.ReadUInt32(); 
     94                currentChunkLength = reader.ReadUInt32(); 
    7195            } 
    7296 
    73             return chunkSize; 
     97            chunkLength = currentChunkLength; 
     98            return true; 
    7499        } 
    75100 
     
    96121        } 
    97122 
    98         ~WaveReader() 
     123        ~RiffReader() 
    99124        { 
    100125            Dispose(false); 
  • trunk/AddIns/WaveAudio/WaveAudio.cs

    r3 r5  
    2323using OmniEncoder.AudioModel.AddInViews; 
    2424 
    25 namespace OmniEncoder.AudioModel.Wave 
     25namespace OmniEncoder.WaveAudio 
    2626{ 
    2727    class WaveAudio : IAudio 
     
    3333        readonly TimeSpan length; 
    3434 
    35         internal WaveAudio(byte[] formatChunk, uint audioSize) 
     35        internal WaveAudio(RiffReader reader) 
    3636        { 
     37            byte[] formatChunk = reader.ReadChunk("fmt "); 
     38 
    3739            // Read the array into a struct. 
    3840            GCHandle handle = GCHandle.Alloc(formatChunk, GCHandleType.Pinned); 
     
    6062            sampleRate = (int)waveFormatEx.SamplesPerSec; 
    6163 
     64            // Use the size of the "data" chunk to calculate the length in seconds. 
     65            uint audioSize; 
     66            reader.AdvanceToChunk("data", out audioSize); 
    6267            int lengthInSeconds = (int)Math.Round(audioSize / (double)waveFormatEx.AvgBytesPerSec); 
    6368            length = new TimeSpan(0, 0, lengthInSeconds); 
  • trunk/AddIns/WaveAudio/WaveAudio.csproj

    r2 r5  
    5454  </ItemGroup> 
    5555  <ItemGroup> 
     56    <Compile Include="RiffReader.cs" /> 
    5657    <Compile Include="Properties\AssemblyInfo.cs" /> 
    5758    <Compile Include="WaveAudio.cs" /> 
    58     <Compile Include="WaveFormat.cs" /> 
     59    <Compile Include="WaveAudioFormat.cs" /> 
    5960    <Compile Include="WaveFormatExChunk.cs" /> 
    60     <Compile Include="WaveReader.cs" /> 
     61    <Compile Include="WaveTag.cs" /> 
     62    <Compile Include="WaveTagFormat.cs" /> 
    6163  </ItemGroup> 
    6264  <ItemGroup> 
     
    6466      <Project>{DEC1B566-9D21-4528-84B7-8D127163AD0B}</Project> 
    6567      <Name>AudioModel.AddInViews</Name> 
     68      <Private>False</Private> 
     69    </ProjectReference> 
     70    <ProjectReference Include="..\..\AddInViews\TagModel.AddInViews\TagModel.AddInViews.csproj"> 
     71      <Project>{E298AEFD-04A2-4E6C-9545-2F6659CC5AF1}</Project> 
     72      <Name>TagModel.AddInViews</Name> 
    6673      <Private>False</Private> 
    6774    </ProjectReference> 
  • trunk/AddIns/WaveAudio/WaveAudioFormat.cs

    r2 r5  
    2323using OmniEncoder.AudioModel.AddInViews; 
    2424 
    25 namespace OmniEncoder.AudioModel.Wave 
     25namespace OmniEncoder.WaveAudio 
    2626{ 
    2727    [AddIn("Wave Audio")] 
    28     public class WaveFormat : IAudioFormat 
     28    public class WaveAudioFormat : IAudioFormat 
    2929    { 
    3030        readonly List<string> extensions; 
    3131 
    32         public WaveFormat() 
     32        public WaveAudioFormat() 
    3333        { 
    3434            extensions = new List<string>(1); 
     
    3636        } 
    3737 
    38         #region IAudioContainer Members 
     38        #region IAudioFormat Members 
    3939 
    4040        public ReadOnlyCollection<string> Extensions 
     
    4343        } 
    4444 
    45         public IAudio GetInfo(string fileName) 
     45        public IAudio GetAudio(string fileName) 
    4646        { 
    47             using (WaveReader reader = new WaveReader(fileName)) 
    48             { 
    49                 byte[] formatChunk = reader.ReadChunk("fmt "); 
    50                 uint audioSize = reader.ReadChunkSize("data"); 
    51                 return new WaveAudio(formatChunk, audioSize); 
    52             } 
     47            using (RiffReader reader = new RiffReader(fileName)) 
     48                return new WaveAudio(reader); 
    5349        } 
    5450 
  • trunk/AddIns/WaveAudio/WaveFormatExChunk.cs

    r2 r5  
    1818 */ 
    1919 
    20 namespace OmniEncoder.AudioModel.Wave 
     20namespace OmniEncoder.WaveAudio 
    2121{ 
    2222    struct WaveFormatEx