Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Прочитать байты из файла (wav) с известной позиции и ими заполнить структуру / 4 сообщений из 4, страница 1 из 1
16.09.2016, 04:12
    #39309959
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прочитать байты из файла (wav) с известной позиции и ими заполнить структуру
Структура:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 <StructLayout(LayoutKind.Sequential)>
  Public Structure WAVEFORMATEX
    Dim wFormatTag As Short        ' format type
    Dim nChannels As Short         ' number of channels (i.e. mono, stereo, etc.)
    Dim nSamplesPerSec As Integer  ' sample rate
    Dim nAvgBytesPerSec As Integer ' for buffer estimation
    Dim nBlockAlign As Short       ' block size of data
    Dim wBitsPerSample As Short    ' Bits Per Sample
    Dim cbSize As Short            ' Size Of (FACT CHUNK)
    'Dim xBytes(11) As Byte        '???
  End Structure


Зачем нужны последние 12 байтов, сейчас не помню (в MDSN их нет, пока закомментировал),
но видимо чтоб не сглючил следующий код, который на VB6 выглядит так:


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
Public Function GetWavFileInfo(ByVal strFile As String) As WavFileInfo
  Dim WavChunkPos As ChunkInfo
  Dim FF      As Integer
  
  GetWavFileInfo.is_wav = False
  
  If Err Then Exit Function
  On Error GoTo 0
  
  ' get fmt Chunk Position
  WavChunkPos = GetWavChunkPos(strFile, "fmt ")

  With WavChunkPos
    ' valid Chunk?
    If .start <> 0 And .length <> 0 Then
      ' read Wave Format
      FF = FreeFile
      Open strFile For Binary As #FF
      Get #FF, .start + 1, GetWavFileInfo.wavformat
      Close #FF
      GetWavFileInfo.is_wav = True
    End If
  End With
  
End Function



GetWavFileInfo.wavformat - это структура WAVEFORMATEX
позицию в файле, с которой читать .start (ну и .length, но он особо и не нужен)
я нашел

Понятно что пихание тупо байтов из файла аккурат в структуру это трюк
но вот как его исполнить на .Net ?
Такой "синтаксис" как в VB6 в .Net похоже не поддерживается.

Ну и еще не понятно как быть с
Код: vbnet
1.
2.
  If Err Then Exit Function
  On Error GoTo 0


хотя Try Catch похоже будет достаточно.

VB6-Модуль я здесь
19670843
полностью выкладывал.
...
Рейтинг: 0 / 0
16.09.2016, 05:40
    #39309965
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прочитать байты из файла (wav) с известной позиции и ими заполнить структуру
Сойдет?
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
 Public Function GetWavFileInfo(ByVal strFile As String) As WavFileInfo
    Dim WavChunkPos As ChunkInfo

    GetWavFileInfo.is_wav = False

    ' get fmt Chunk Position
    WavChunkPos = GetWavChunkPos(strFile, "fmt ")

    ' valid Chunk?
    If WavChunkPos.start <> 0 And WavChunkPos.length <> 0 Then
      ' read Wave Format
      Try
        Using fs As New IO.FileStream(strFile, IO.FileMode.Open, IO.FileAccess.Read)
          Using br As New IO.BinaryReader(fs)
            br.ReadBytes(WavChunkPos.start) 'просто чтоб передвинуться к чтению формата
            With GetWavFileInfo.wav_format
              .wFormatTag = br.ReadInt16()
              .nChannels = br.ReadInt16()
              .nSamplesPerSec = br.ReadInt32()
              .nAvgBytesPerSec = br.ReadInt32()
              .nBlockAlign = br.ReadInt16()
              .wBitsPerSample = br.ReadInt16()
              .cbSize = br.ReadInt16()
            End With
          End Using
        End Using
        GetWavFileInfo.is_wav = True
      Catch
      End Try
    End If

  End Function



Хотя помойму в .cbSize я кладу бред сивой кобылы, но он мне и не нужен, все красивые слова про описание формата (PCM/ADPCM, моно/стерео, Bit/kHz) берутся из того что до, счас задача отобразить свойства wav-а.
...
Рейтинг: 0 / 0
16.09.2016, 05:43
    #39309967
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прочитать байты из файла (wav) с известной позиции и ими заполнить структуру
Дмитрий77Сойдет?Да, если работает.
Дмитрий77
Код: c#
1.
br.ReadBytes(WavChunkPos.start) 'просто чтоб передвинуться к чтению формата

Для этого есть FileStream.Seek.
...
Рейтинг: 0 / 0
16.09.2016, 06:52
    #39309982
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прочитать байты из файла (wav) с известной позиции и ими заполнить структуру
Да, работает.
Проверяет что это wav- через mmioOpen...mmioClose + не спотыкаемся на заполнении структуры(можно работать с файлом), ну и пишет для юзера типа "PCM 8,000 kHz; 8 Bit; Mono"после форматирования:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
 Public Function GetWavFormatName(w_FormatTag As Short) As String
    Select Case w_FormatTag
      Case 1
        GetWavFormatName = "PCM"
      Case 2
        GetWavFormatName = "Microsoft ADPCM"
      Case 6
        GetWavFormatName = "CCITT A-law"
      Case 7
        GetWavFormatName = "CCITT u-law"
      Case 17
        GetWavFormatName = "IMA ADPCM"
      Case 20
        GetWavFormatName = "ITU G.723 ADPCM (Yamaha)"
      Case 49
        GetWavFormatName = "GSM 6.10"
      Case 64
        GetWavFormatName = "ITU G.721 ADPCM"
      Case 66
        GetWavFormatName = "Microsoft G.723.1"
      Case 80
        GetWavFormatName = "MPEG"
      Case 85
        GetWavFormatName = "MPEG Layer-3"
      Case Else
        GetWavFormatName = CStr(w_FormatTag) & "(Unknown)"
    End Select
  End Function

  Public Function GetWavFormatDetails(n_SamplesPerSec As Integer, w_BitsPerSample As Short, _
   n_Channels As Short) As String
    Dim fmt_SamplesPerSec As String
    fmt_SamplesPerSec = CStr(n_SamplesPerSec)
    If Strings.Len(fmt_SamplesPerSec) > 3 Then
      fmt_SamplesPerSec = Strings.Left(fmt_SamplesPerSec, Strings.Len(fmt_SamplesPerSec) - 3) & "," & Strings.Right(fmt_SamplesPerSec, 3)
    Else
      fmt_SamplesPerSec = "0," & Format(fmt_SamplesPerSec, "000")
    End If
    fmt_SamplesPerSec = fmt_SamplesPerSec & " kHz"
    GetWavFormatDetails = fmt_SamplesPerSec & "; " & CStr(w_BitsPerSample) & " Bit; " & _
     IIf((n_Channels = 1), "Mono", "Stereo")
  End Function

Алексей КДля этого есть FileStream.Seek.
А, не сообразил что стримом надо двигать, а не ридером.
Тогда так
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    ' valid Chunk?
    If WavChunkPos.start <> 0 And WavChunkPos.length <> 0 Then
      ' read Wave Format
      Try
        Using fs As New IO.FileStream(strFile, IO.FileMode.Open, IO.FileAccess.Read)
          fs.Seek(WavChunkPos.start, 0) 'чтоб передвинуться к чтению формата
          Using br As New IO.BinaryReader(fs)
            With GetWavFileInfo.wav_format
              .wFormatTag = br.ReadInt16()
              .nChannels = br.ReadInt16()
              .nSamplesPerSec = br.ReadInt32()
              .nAvgBytesPerSec = br.ReadInt32()
              .nBlockAlign = br.ReadInt16()
              .wBitsPerSample = br.ReadInt16()
              .cbSize = br.ReadInt16()
            End With
          End Using
        End Using
        GetWavFileInfo.is_wav = True
      Catch
      End Try
    End If


Да там 20 байт всего перед "fmt ". Хотя как вы написали конечно корректней.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Прочитать байты из файла (wav) с известной позиции и ими заполнить структуру / 4 сообщений из 4, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]