Domanda

In Assemblaggio .NET MSCORLIB SYSTEM SYSTEM.IO SPESPACE, Sto usando Readint16 () Metodo per loop tramite byte di dati audio e dumping Valori interi firmati in un file di testo.Come si interpreta i due valori associati a una tasso di campionamento?Cioè se ho un secondo di dati monologi ci saranno 88200 byte, quindi utilizzando Readint16 () restituisce 88200 interi discreti.Questa è troppe informazioni, dovrei avere solo 44100 numeri interi.Quindi devo usare un metodo diverso o forse avanzare il ciclo di 1 per ogni iterazione.

Molte grazie .......... Topolino

È stato utile?

Soluzione

using System;
using System.IO;

public struct WaveFormat
{

    private short m_FormatTag;       // most often PCM = 1      
    private short m_nChannels;       // number of channels      
    private int m_SamplesPerSecond;  // samples per second eg 44100     
    private int m_AvgBytesPerSecond; // bytes per second eg 176000      
    private short m_BlockAlign;      // blockalign (byte per sample) eg 4 bytes         
    private short m_BitsPerSample;   // bits per sample, 8, 16, 24

    public WaveFormat(byte BPS, int SPS, byte nChn)
    {
        m_FormatTag = 1; //PCM
        m_nChannels = nChn;
        m_SamplesPerSecond = SPS;
        m_BitsPerSample = BPS;
        m_BlockAlign = (short)(m_nChannels * m_BitsPerSample / 8);
        m_AvgBytesPerSecond = (int)(m_BlockAlign * m_SamplesPerSecond);
    }
    public short FormatTag
    {
        get { return m_FormatTag; }
        set { m_FormatTag = value; }
    }
    public short Channels
    {
        get { return m_nChannels; }
    }
    public int SamplesPerSecond
    {
        get { return m_SamplesPerSecond; }
    }
    public int AvgBytesPerSecond
    {
        get { return m_AvgBytesPerSecond; }
    }
    public short BlockAlign
    {
        get { return m_BlockAlign; }
    }
    public short BitsPerSample
    {
        get { return m_BitsPerSample; }
    }
    public void Read(BinaryReader br)
    {
        m_FormatTag = br.ReadInt16();
        m_nChannels = br.ReadInt16();
        m_SamplesPerSecond = br.ReadInt32();
        m_AvgBytesPerSecond = br.ReadInt32();
        m_BlockAlign = br.ReadInt16();
        m_BitsPerSample = br.ReadInt16();
    }
    public void Write(BinaryWriter bw)
    {
        bw.Write(m_FormatTag);
        bw.Write(m_nChannels);
        bw.Write(m_SamplesPerSecond);
        bw.Write(m_AvgBytesPerSecond);
        bw.Write(m_BlockAlign);
        bw.Write(m_BitsPerSample);
    }
    public override string ToString()
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.AppendLine("FormatTag:         " + m_FormatTag.ToString());
        sb.AppendLine("nChannels:         " + m_nChannels.ToString());
        sb.AppendLine("SamplesPerSecond:  " + m_SamplesPerSecond.ToString());
        sb.AppendLine("AvgBytesPerSecond: " + m_AvgBytesPerSecond.ToString());
        sb.AppendLine("BlockAlign:        " + m_BlockAlign.ToString());
        sb.AppendLine("BitsPerSample:     " + m_BitsPerSample.ToString());
        return sb.ToString();
    }
}
.

Altri suggerimenti

Generalmente quando leggi gli array di dati il tuo codice dovrebbe apparire come:

for(int i = 0; i < totalNumberOfEntries; i++)
{
  // read all data for this entry
  var component1 = reader.ReadXXX();
  var component2 = reader.ReadXXX();

  // deal with data for this entry
  someEntryStroage.Add(new Entry(component1, component2);
}
.

Molto probabilmente (non conosco il formato di file wave) nel tuo caso è necessario leggere coppie di valori INT16 (se i campioni sono insieme) o leggere i canali separatamente se i dati per un canale sono dopo l'altro.

Devi leggere i ChunkinFos.I dati-chunk ti dicono quanti byte devi leggere.The Waveformat ti dice ho molto nella mediaBySpersecond hai, e molto altro ancora.Ho del codice VB ...

ha convertito il codice VB con SharpDevelop in C # forse aiuta un po '...

using System;
using System.IO;

public class ChunkInfo
{
    private byte[] m_Header;
    private long m_Length;
    private long m_OffSet;
    public ChunkInfo(string Header)
    {
        m_Header = new byte[Header.Length];
        for (int i = 0; i <= m_Header.GetUpperBound(0); i++)
        {
            m_Header[i] = (byte)Header[i];
        }
    }
    public ChunkInfo(byte[] Header)
    {
        m_Header = Header;
    }
    public void Read(BinaryReader br)
    {
        m_OffSet = SearchOffset(br);
        if (m_OffSet >= 0)
        {
            br.BaseStream.Position = m_OffSet + m_Header.Length;
            m_Length = br.ReadInt32();
        }
    }
    public void Write(BinaryWriter bw)
    {
        bw.Write(m_Header);
        bw.Write(m_Length);
    }
    public long Length
    {
        get { return m_Length; }
    }
    public long OffSet
    {
        get { return m_OffSet; }
    }
    private long SearchOffset(BinaryReader br)
    {
        byte[] haystack = null;
        bool found = false;
        long offset = 0;
        long basepos = 0;
        int hlength = 260;
        long basepos_grow = hlength - m_Header.Length;
        while (!(found || (basepos >= br.BaseStream.Length)))
        {
            br.BaseStream.Position = basepos;
            haystack = br.ReadBytes(hlength);
            offset = BoyerMooreHorspool.find(haystack, m_Header);
            found = offset >= 0;
            if (found)
            {
                offset += basepos;
                break; 
            }
            else
            {
                basepos += basepos_grow;
            }
        }
        return offset;
    }
}
public static class BoyerMooreHorspool
{
    //detects a needle in the haystack
    const int UBYTE_MAX = 255;
    static int[] bad_char_skip4 = new int[UBYTE_MAX + 3];
    static int[] bad_char_skip8 = new int[UBYTE_MAX + 3];
    static bool IsInitialized = false;
    public static void init()
    {
        //little optimization for needles with length 4 or 8
        for (int i = 0; i <= UBYTE_MAX + 2; i++)
        {
            bad_char_skip4[i] = 4;
            bad_char_skip8[i] = 8;
        }
        IsInitialized = true;
    }
    public static int find(byte[] haystack, byte[] needle, int start = 0)
    {
        if (!IsInitialized) init();
        int i_n = 0;
        //needle index
        int n_n = needle.Length;
        int[] bad_char_skip = null;
        switch (n_n)
        {
            case 4:
                bad_char_skip = bad_char_skip4;
                break;
            case 8:
                bad_char_skip = bad_char_skip8;
                break;
            default:
                bad_char_skip = new int[UBYTE_MAX + 3];
                for (i_n = 0; i_n <= UBYTE_MAX + 2; i_n++)
                {
                    bad_char_skip[i_n] = n_n;
                }

                break;
        }
        int ifind = -1;
        //if not found then return - 1
        int i_h = start;
        //haystack index
        int n_h = haystack.Length;
        if (n_n > n_h)
            throw new ArgumentOutOfRangeException("needle", "needle is to long");
        int last = n_n - 1;
        for (i_n = 0; i_n <= last - 1; i_n++)
        {
            bad_char_skip[needle[i_n]] = last - i_n;
        }
        byte bcs = 0;
        int bhs = 0;
        while ((n_h - start) >= n_n)
        {
            i_n = last;
            while (haystack[i_h + i_n] == needle[i_n])
            {
                i_n -= 1;
                if (i_n == 0)
                {
                    ifind = i_h;
                    break; 
                }
            }
            bhs = haystack[i_h + last];
            bcs = (byte)(bad_char_skip[bhs]);
            n_h -= bcs;
            i_h += bcs;
        }
        return ifind;
    }
}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top