Problem mit Audio (Singles vs. Bytes)

03/12/2011 - 16:26 von Hermie | Report spam
Hallo,

ich lese aus einer Wav-Datei einen Teil aus.
Bisher habe ich dafür "Get" mit Bytes benutzt.
Das funktioniert wunderbar.

Nun wollte ich das Ganze, damit ich mir die Umrechnungen sparen kann,
auf Singles umstellen. Aber die Resultate sind nicht dieselben.

Falls jemand den Nerv hat, sich das mal anzuschauen, würde ich mich sehr
freuen...

Vielen Dank.
Hermann

Option Explicit

Private Sub Form_Load()

Dim iReadFile%
iReadFile = FreeFile

Dim sPath$
sPath = "c:\mywav.wav"

Dim lStart&
lStart = 1080

Dim lByteDuration&
lByteDuration = 3000

Dim bt() As Byte
ReDim bt(0 To lByteDuration)

Dim sng() As Single
ReDim sng(0 To (lByteDuration \ 2))

Open sPath For Binary As iReadFile
Get #iReadFile, lStart, sng 'einmal füllen wir die singles
Get #iReadFile, lStart, bt() 'einmal füllen wir die bytes
Close #iReadFile

Dim l&
For l = 0 To UBound(bt) Step 2

Dim lByteLow&
Dim lByteHigh&
lByteHigh = bt(l + 1)
lByteLow = bt(l)

If (lByteHigh > 128) Then
lByteHigh = (lByteHigh - 256)
End If
If (lByteLow > 128) Then
lByteLow = (lByteLow - 256)
End If

Dim ByteSample&
ByteSample = ShiftLeft(lByteHigh, 8) Or (lByteLow And 255)

Dim SampleFromBytes As Single
SampleFromBytes = (ByteSample / 32768)

Dim SampleFromSingle As Single
SampleFromSingle = sng(l)

Debug.Assert SampleFromSingle = SampleFromBytes 'das ist leider
nicht gleich. Nur SampleFromBytes ist korrekt

Next l

End Sub

Public Function ShiftLeft(ByVal Value As Long, ByVal ShiftCount As Long)
As Long
' by Jost Schwider, jost@schwider.de, 20011001
Select Case ShiftCount
Case 0&
ShiftLeft = Value
Case 1&
If Value And &H40000000 Then
ShiftLeft = (Value And &H3FFFFFFF) * &H2& Or &H80000000
Else
ShiftLeft = (Value And &H3FFFFFFF) * &H2&
End If
Case 2&
If Value And &H20000000 Then
ShiftLeft = (Value And &H1FFFFFFF) * &H4& Or &H80000000
Else
ShiftLeft = (Value And &H1FFFFFFF) * &H4&
End If
Case 3&
If Value And &H10000000 Then
ShiftLeft = (Value And &HFFFFFFF) * &H8& Or &H80000000
Else
ShiftLeft = (Value And &HFFFFFFF) * &H8&
End If
Case 4&
If Value And &H8000000 Then
ShiftLeft = (Value And &H7FFFFFF) * &H10& Or &H80000000
Else
ShiftLeft = (Value And &H7FFFFFF) * &H10&
End If
Case 5&
If Value And &H4000000 Then
ShiftLeft = (Value And &H3FFFFFF) * &H20& Or &H80000000
Else
ShiftLeft = (Value And &H3FFFFFF) * &H20&
End If
Case 6&
If Value And &H2000000 Then
ShiftLeft = (Value And &H1FFFFFF) * &H40& Or &H80000000
Else
ShiftLeft = (Value And &H1FFFFFF) * &H40&
End If
Case 7&
If Value And &H1000000 Then
ShiftLeft = (Value And &HFFFFFF) * &H80& Or &H80000000
Else
ShiftLeft = (Value And &HFFFFFF) * &H80&
End If
Case 8&
If Value And &H800000 Then
ShiftLeft = (Value And &H7FFFFF) * &H100& Or &H80000000
Else
ShiftLeft = (Value And &H7FFFFF) * &H100&
End If
Case 9&
If Value And &H400000 Then
ShiftLeft = (Value And &H3FFFFF) * &H200& Or &H80000000
Else
ShiftLeft = (Value And &H3FFFFF) * &H200&
End If
Case 10&
If Value And &H200000 Then
ShiftLeft = (Value And &H1FFFFF) * &H400& Or &H80000000
Else
ShiftLeft = (Value And &H1FFFFF) * &H400&
End If
Case 11&
If Value And &H100000 Then
ShiftLeft = (Value And &HFFFFF) * &H800& Or &H80000000
Else
ShiftLeft = (Value And &HFFFFF) * &H800&
End If
Case 12&
If Value And &H80000 Then
ShiftLeft = (Value And &H7FFFF) * &H1000& Or &H80000000
Else
ShiftLeft = (Value And &H7FFFF) * &H1000&
End If
Case 13&
If Value And &H40000 Then
ShiftLeft = (Value And &H3FFFF) * &H2000& Or &H80000000
Else
ShiftLeft = (Value And &H3FFFF) * &H2000&
End If
Case 14&
If Value And &H20000 Then
ShiftLeft = (Value And &H1FFFF) * &H4000& Or &H80000000
Else
ShiftLeft = (Value And &H1FFFF) * &H4000&
End If
Case 15&
If Value And &H10000 Then
ShiftLeft = (Value And &HFFFF&) * &H8000& Or &H80000000
Else
ShiftLeft = (Value And &HFFFF&) * &H8000&
End If
Case 16&
If Value And &H8000& Then
ShiftLeft = (Value And &H7FFF&) * &H10000 Or &H80000000
Else
ShiftLeft = (Value And &H7FFF&) * &H10000
End If
Case 17&
If Value And &H4000& Then
ShiftLeft = (Value And &H3FFF&) * &H20000 Or &H80000000
Else
ShiftLeft = (Value And &H3FFF&) * &H20000
End If
Case 18&
If Value And &H2000& Then
ShiftLeft = (Value And &H1FFF&) * &H40000 Or &H80000000
Else
ShiftLeft = (Value And &H1FFF&) * &H40000
End If
Case 19&
If Value And &H1000& Then
ShiftLeft = (Value And &HFFF&) * &H80000 Or &H80000000
Else
ShiftLeft = (Value And &HFFF&) * &H80000
End If
Case 20&
If Value And &H800& Then
ShiftLeft = (Value And &H7FF&) * &H100000 Or &H80000000
Else
ShiftLeft = (Value And &H7FF&) * &H100000
End If
Case 21&
If Value And &H400& Then
ShiftLeft = (Value And &H3FF&) * &H200000 Or &H80000000
Else
ShiftLeft = (Value And &H3FF&) * &H200000
End If
Case 22&
If Value And &H200& Then
ShiftLeft = (Value And &H1FF&) * &H400000 Or &H80000000
Else
ShiftLeft = (Value And &H1FF&) * &H400000
End If
Case 23&
If Value And &H100& Then
ShiftLeft = (Value And &HFF&) * &H800000 Or &H80000000
Else
ShiftLeft = (Value And &HFF&) * &H800000
End If
Case 24&
If Value And &H80& Then
ShiftLeft = (Value And &H7F&) * &H1000000 Or &H80000000
Else
ShiftLeft = (Value And &H7F&) * &H1000000
End If
Case 25&
If Value And &H40& Then
ShiftLeft = (Value And &H3F&) * &H2000000 Or &H80000000
Else
ShiftLeft = (Value And &H3F&) * &H2000000
End If
Case 26&
If Value And &H20& Then
ShiftLeft = (Value And &H1F&) * &H4000000 Or &H80000000
Else
ShiftLeft = (Value And &H1F&) * &H4000000
End If
Case 27&
If Value And &H10& Then
ShiftLeft = (Value And &HF&) * &H8000000 Or &H80000000
Else
ShiftLeft = (Value And &HF&) * &H8000000
End If
Case 28&
If Value And &H8& Then
ShiftLeft = (Value And &H7&) * &H10000000 Or &H80000000
Else
ShiftLeft = (Value And &H7&) * &H10000000
End If
Case 29&
If Value And &H4& Then
ShiftLeft = (Value And &H3&) * &H20000000 Or &H80000000
Else
ShiftLeft = (Value And &H3&) * &H20000000
End If
Case 30&
If Value And &H2& Then
ShiftLeft = (Value And &H1&) * &H40000000 Or &H80000000
Else
ShiftLeft = (Value And &H1&) * &H40000000
End If
Case 31&
If Value And &H1& Then
ShiftLeft = &H80000000
Else
ShiftLeft = &H0&
End If
End Select
End Function
 

Lesen sie die antworten

#1 Wolfgang Enzinger
03/12/2011 - 17:26 | Warnen spam
Hermie wrote:

Dim l&
For l = 0 To UBound(bt) Step 2

Dim lByteLow&
Dim lByteHigh&
lByteHigh = bt(l + 1)
lByteLow = bt(l)

If (lByteHigh > 128) Then
lByteHigh = (lByteHigh - 256)
End If
If (lByteLow > 128) Then
lByteLow = (lByteLow - 256)
End If

Dim ByteSample&
ByteSample = ShiftLeft(lByteHigh, 8) Or (lByteLow And 255)



nach flüchtiger Durchsicht sieht das für mich so aus, als ob du den
Single-Wert aus 2 Bytes zusammenbasteln willst. Ein Single hat aber 4 Bytes.
Davon abgesehen ist Single ein Floating-Point-Datentyp; ich glaube daher kaum,
dass du mit Shiften einzelner Bytes zum richtigen Ergebnis kommen kannst.

Ich würde daher drauf tippen, dass die "direkt" als Single gelesenen Werte die
richtigen sind (wenn denn tatsàchlich Single-Werte da drinstehen; hab mir das
WAV-Format jetzt nicht nàher angeschaut; sind das vllt. in Wirklichkeit
Integers mit 2 Byte?).

Viele Grüsse,
Wolfgang

Abstimmung über Änderung der de-Einrichtungsregeln - mitmachen!
http://groups.google.com/group/de.a...aba04046f1

Ähnliche fragen