Domanda

In non compresso situazione so che ho bisogno di leggere l'intestazione wav, tirare fuori il numero di canali, bit e frequenza di campionamento e di lavoro fuori da lì:(canali) * (bit) * (campioni/s) * (secondi) = (dimensione file)

C'è un modo più semplice - una libreria, o in qualcosa .net framework, forse?

Come posso fare questo se l' .wav file è compresso con il codec mpeg per esempio)?

È stato utile?

Soluzione

Si può prendere in considerazione le mciSendString(...) la funzione (di controllo di errore è omessi per chiarezza):

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace Sound
{
    public static class SoundInfo
    {
        [DllImport("winmm.dll")]
        private static extern uint mciSendString(
            string command,
            StringBuilder returnValue,
            int returnLength,
            IntPtr winHandle);

        public static int GetSoundLength(string fileName)
        {
            StringBuilder lengthBuf = new StringBuilder(32);

            mciSendString(string.Format("open \"{0}\" type waveaudio alias wave", fileName), null, 0, IntPtr.Zero);
            mciSendString("status wave length", lengthBuf, lengthBuf.Capacity, IntPtr.Zero);
            mciSendString("close wave", null, 0, IntPtr.Zero);

            int length = 0;
            int.TryParse(lengthBuf.ToString(), out length);

            return length;
        }
    }
}

Altri suggerimenti

Download NAudio.dll dal link http://naudio.codeplex.com/

e poi usare questa funzione

public static TimeSpan GetWavFileDuration(string fileName)       
{     
    WaveFileReader wf = new WaveFileReader(fileName);
    return wf.TotalTime; 
}

si ottiene la Durata

Non per togliere nulla la risposta già accettato, ma sono stato in grado di ottenere la durata di un file audio in diversi formati, tra cui AC3, che è quello che mi serviva al momento) utilizzando il Microsoft.DirectX.AudioVideoPlayBack spazio dei nomi.Questo è parte del DirectX 9.0 per il Codice Gestito.L'aggiunta di un riferimento al fatto che il mio codice di semplice come questo...

Public Shared Function GetDuration(ByVal Path As String) As Integer
    If File.Exists(Path) Then
        Return CInt(New Audio(Path, False).Duration)
    Else
        Throw New FileNotFoundException("Audio File Not Found: " & Path)
    End If
End Function

Ed è abbastanza veloce, troppo!Ecco un riferimento per il Audio classe.

Ho avuto difficoltà con l'esempio del MediaPlayer-classe di cui sopra.Si potrebbe richiedere un certo tempo, prima che il giocatore ha aperto il file.Nel "mondo reale", è necessario registrarsi per il MediaOpened-evento, dopo che ha sparato il NaturalDuration è valido.In una console-app devi solo aspettare un paio di secondi dopo l'apertura.

using System;
using System.Text;
using System.Windows.Media;
using System.Windows;

namespace ConsoleApplication2
{
  class Program
  {
    static void Main(string[] args)
    {
      if (args.Length == 0)
        return;
      Console.Write(args[0] + ": ");
      MediaPlayer player = new MediaPlayer();
      Uri path = new Uri(args[0]);
      player.Open(path);
      TimeSpan maxWaitTime = TimeSpan.FromSeconds(10);
      DateTime end = DateTime.Now + maxWaitTime;
      while (DateTime.Now < end)
      {
        System.Threading.Thread.Sleep(100);
        Duration duration = player.NaturalDuration;
        if (duration.HasTimeSpan)
        {
          Console.WriteLine(duration.TimeSpan.ToString());
          break;
        }
      }
      player.Close();
    }
  }
}

Tenta di codice riportato di seguito da Come determinare la lunghezza di una .file wav in C#

    string path = @"c:\test.wav";
    WaveReader wr = new WaveReader(File.OpenRead(path));
    int durationInMS = wr.GetDurationInMS();
    wr.Close();

Sì, C'è una libreria che può essere utilizzato per ottenere il tempo di durata del file Audio.Questa libreria offre molte più funzionalità.

TagLib

TagLib è distribuito sotto la GNU Lesser General Public License (LGPL) e la Mozilla Public License (MPL).

Ho implementato sotto il codice che restituisce il tempo di durata in secondi.

using TagLib.Mpeg;

public static double GetSoundLength(string FilePath)
{
    AudioFile ObjAF = new AudioFile(FilePath);
    return ObjAF.Properties.Duration.TotalSeconds;
}

Si potrebbe scoprire che il XNA biblioteca ha qualche supporto per lavorare con il WAV etc.se siete disposti ad andare a nanna.Esso è progettato per lavorare con C# per la programmazione di videogiochi, quindi potrebbe solo prendere cura di tutto ciò di cui hai bisogno.

C'è un po ' di tutorial (con - presumibilmente - codice di lavoro è possibile sfruttare) oltre a CodeProject.

L'unica cosa che devi essere un po ' attenti è che è perfettamente "normale" per un file WAV per essere composto di vari pezzi in modo da dovete scoot su tutto il file per assicurarsi che tutti i pezzi sono contabilizzate.

Che cosa è esattamente la propria applicazione facendo con compresso Wav?Compressi i file WAV sono sempre difficili - e cerco sempre di utilizzare un contenitore alternativo formato, in questo caso, come OGG o WMA.XNA librerie tendono ad essere progettato per lavorare con formati specifici - anche se è possibile che all'interno di un ANIMALE troverete un più generico wav metodo di riproduzione.Una possibile alternativa è cercare di SDL C# porta, anche se ho sempre e solo usato per giocare non compresso Wav - una volta aperto si può interrogare il numero di campioni per determinare la lunghezza.

Devo dire MediaInfo, Ho utilizzato per più di un anno con un encoding audio/video applicazione su cui sto lavorando.Esso fornisce tutte le informazioni per i file wav con quasi ogni altro formato.

MediaInfoDll Viene fornito con un esempio di codice C# su come farlo funzionare.

Ho intenzione di assumere che siete un po ' di familiarità con la struttura di un .File WAV :esso contiene un WAVEFORMATEX intestazione struct, seguita da un certo numero di altre strutture (o "pezzi"), contenente informazioni di vario tipo.Vedere Wikipedia per ulteriori informazioni sul formato di file.

Primo, scorrere l' .file wav e aggiungete il unpadded lunghezze dei "dati" pezzi " (i "dati" pezzo contiene i dati audio per il file;di solito c'è solo uno di questi, ma è possibile che ci potrebbero essere più di uno).Si dispone ora di totale la dimensione, in byte, di dati audio.

Avanti, ottenere il "media byte al secondo membro della WAVEFORMATEX intestazione struttura del file.

Infine, dividere la dimensione totale dei dati audio dalla media di byte al secondo - questo vi darà la durata del file, in pochi secondi.

Questo funziona abbastanza bene per non compressi e compressi.

tempo = FileLength / (Frequenza di Campionamento * Canali * Bit per campione /8)

ho testato soffiò il codice verrebbe a mancare,formati di file come "\\ip\dir\*.wav'

 public static class SoundInfo
   {
     [DllImport("winmm.dll")]
     private static extern uint mciSendString
     (
        string command,
        StringBuilder returnValue,
        int returnLength,
        IntPtr winHandle
     );

     public static int GetSoundLength(string fileName)
      {
        StringBuilder lengthBuf = new StringBuilder(32);

        mciSendString(string.Format("open \"{0}\" type waveaudio alias wave", fileName), null, 0, IntPtr.Zero);
        mciSendString("status wave length", lengthBuf, lengthBuf.Capacity, IntPtr.Zero);
        mciSendString("close wave", null, 0, IntPtr.Zero);

        int length = 0;
        int.TryParse(lengthBuf.ToString(), out length);

        return length;
    }
}

mentre naudio opere

    public static int GetSoundLength(string fileName)
     {
        using (WaveFileReader wf = new WaveFileReader(fileName))
        {
            return (int)wf.TotalTime.TotalMilliseconds;
        }
     }`
Imports System.IO
Imports System.Text

Imports System.Math
Imports System.BitConverter

Public Class PulseCodeModulation
    ' Pulse Code Modulation WAV (RIFF) file layout

    ' Header chunk

    ' Type   Byte Offset  Description
    ' Dword       0       Always ASCII "RIFF"
    ' Dword       4       Number of bytes in the file after this value (= File Size - 8)
    ' Dword       8       Always ASCII "WAVE"

    ' Format Chunk

    ' Type   Byte Offset  Description
    ' Dword       12      Always ASCII "fmt "
    ' Dword       16      Number of bytes in this chunk after this value
    ' Word        20      Data format PCM = 1 (i.e. Linear quantization)
    ' Word        22      Channels Mono = 1, Stereo = 2
    ' Dword       24      Sample Rate per second e.g. 8000, 44100
    ' Dword       28      Byte Rate per second (= Sample Rate * Channels * (Bits Per Sample / 8))
    ' Word        32      Block Align (= Channels * (Bits Per Sample / 8))
    ' Word        34      Bits Per Sample e.g. 8, 16

    ' Data Chunk

    ' Type   Byte Offset  Description
    ' Dword       36      Always ASCII "data"
    ' Dword       40      The number of bytes of sound data (Samples * Channels * (Bits Per Sample / 8))
    ' Buffer      44      The sound data

    Dim HeaderData(43) As Byte

    Private AudioFileReference As String

    Public Sub New(ByVal AudioFileReference As String)
        Try
            Me.HeaderData = Read(AudioFileReference, 0, Me.HeaderData.Length)
        Catch Exception As Exception
            Throw
        End Try

        'Validate file format

        Dim Encoder As New UTF8Encoding()

        If "RIFF" <> Encoder.GetString(BlockCopy(Me.HeaderData, 0, 4)) Or _
            "WAVE" <> Encoder.GetString(BlockCopy(Me.HeaderData, 8, 4)) Or _
            "fmt " <> Encoder.GetString(BlockCopy(Me.HeaderData, 12, 4)) Or _
            "data" <> Encoder.GetString(BlockCopy(Me.HeaderData, 36, 4)) Or _
            16 <> ToUInt32(BlockCopy(Me.HeaderData, 16, 4), 0) Or _
            1 <> ToUInt16(BlockCopy(Me.HeaderData, 20, 2), 0) _
        Then
            Throw New InvalidDataException("Invalid PCM WAV file")
        End If

        Me.AudioFileReference = AudioFileReference
    End Sub

    ReadOnly Property Channels() As Integer
        Get
            Return ToUInt16(BlockCopy(Me.HeaderData, 22, 2), 0) 'mono = 1, stereo = 2
        End Get
    End Property

    ReadOnly Property SampleRate() As Integer
        Get
            Return ToUInt32(BlockCopy(Me.HeaderData, 24, 4), 0) 'per second
        End Get
    End Property

    ReadOnly Property ByteRate() As Integer
        Get
            Return ToUInt32(BlockCopy(Me.HeaderData, 28, 4), 0) 'sample rate * channels * (bits per channel / 8)
        End Get
    End Property

    ReadOnly Property BlockAlign() As Integer
        Get
            Return ToUInt16(BlockCopy(Me.HeaderData, 32, 2), 0) 'channels * (bits per sample / 8)
        End Get
    End Property

    ReadOnly Property BitsPerSample() As Integer
        Get
            Return ToUInt16(BlockCopy(Me.HeaderData, 34, 2), 0)
        End Get
    End Property

    ReadOnly Property Duration() As Integer
        Get
            Dim Size As Double = ToUInt32(BlockCopy(Me.HeaderData, 40, 4), 0)
            Dim ByteRate As Double = ToUInt32(BlockCopy(Me.HeaderData, 28, 4), 0)
            Return Ceiling(Size / ByteRate)
        End Get
    End Property

    Public Sub Play()
        Try
            My.Computer.Audio.Play(Me.AudioFileReference, AudioPlayMode.Background)
        Catch Exception As Exception
            Throw
        End Try
    End Sub

    Public Sub Play(playMode As AudioPlayMode)
        Try
            My.Computer.Audio.Play(Me.AudioFileReference, playMode)
        Catch Exception As Exception
            Throw
        End Try
    End Sub

    Private Function Read(AudioFileReference As String, ByVal Offset As Long, ByVal Bytes As Long) As Byte()
        Dim inputFile As System.IO.FileStream

        Try
            inputFile = IO.File.Open(AudioFileReference, IO.FileMode.Open)
        Catch Exception As FileNotFoundException
            Throw New FileNotFoundException("PCM WAV file not found")
        Catch Exception As Exception
            Throw
        End Try

        Dim BytesRead As Long
        Dim Buffer(Bytes - 1) As Byte

        Try
            BytesRead = inputFile.Read(Buffer, Offset, Bytes)
        Catch Exception As Exception
            Throw
        Finally
            Try
                inputFile.Close()
            Catch Exception As Exception
                'Eat the second exception so as to not mask the previous exception
            End Try
        End Try

        If BytesRead < Bytes Then
            Throw New InvalidDataException("PCM WAV file read failed")
        End If

        Return Buffer
    End Function

    Private Function BlockCopy(ByRef Source As Byte(), ByVal Offset As Long, ByVal Bytes As Long) As Byte()
        Dim Destination(Bytes - 1) As Byte

        Try
            Buffer.BlockCopy(Source, Offset, Destination, 0, Bytes)
        Catch Exception As Exception
            Throw
        End Try

        Return Destination
    End Function
End Class

Scaricare "PresentationCore.dll" e "WindowsBase.dll" da:

http://www.search-dll.com/dll-files/download/windowsbase.dll.html

Incollare il file in applicazione della cartella bin di riferimento.Ora dovrebbe funzionare.

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