Pregunta

En el espacio de nombres MScorlib System.IO, estoy usando el método ReadInt16 () para bucle a través de bytes de datos de audio y dumping firmados valores enteros en un archivo de texto.¿Cómo interpreta a uno los dos valores asociados con una tasa de muestra?Es decir, si tengo un segundo de los datos mono, habrá 88200 bytes, por lo tanto, usar Readint16 () devuelve 88200 enteros discretos.Esta es demasiada información, solo debería tener 44100 enteros.Entonces, debo usar un método diferente o tal vez avanzar el bucle en 1 por cada iteración.

Muchas gracias .......... Mickey

¿Fue útil?

Solución

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();
    }
}

Otros consejos

Generalmente cuando lee las matrices de datos que debe parecer su código:

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);
}

Lo más probable (no conozco el formato de archivo WAVE) en su caso, es necesario leer pares de valores INT16 (si las muestras están juntas) o leer los canales por separado si los datos de un canal se traslan.

Debes leer los Chunkinfos.El Data-Chunk le dice cuántos bytes tiene que leer.El Formato Wavefat le dice a Ho Mucho normalByTespersecundo que tiene, y mucho más.Tengo algún código VB ...

HA CONVERTIDO EL CÓDIGO VB CON SECUPARDO ABALLO A C # Tal vez ayuda un poco ...

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;
    }
}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top