Visual Basic -- Wave Datei soll im Arbeitsspeicher zwischengepuffert werden, wie ?

Clocker 2800+

Lt. Commander
Registriert
Apr. 2007
Beiträge
1.409
Hallo,

ich habe in Visual Basic 6.0 ein Programm geschrieben, dass einfach den Sound (z.b. Musik, ...) halt alles, was aus dem Lautsprächer kommt aufnimmt. So weit so gut.

Ich hab das jetzt so gemacht, dass am Anfang der Aufnahme eine Wave Datei auf der Festplatte erstellt wird, und dann die Datei immer weiter vollgeschrieben wird. Sprich, die Datei bleibt Programmintern geöffnet, und es wird einfach immer wieder was hineingeschrieben (und so weiter), bis die Aufnahme zu Ende ist.

Das Problem ist nur, wenn ich aufnehme, dass immer auf die Festplatte zugegriffen wird, was das System sehr ausbremst. Weil ja die Datei immer weiter vollgeschrieben wird.

Meine Frage:


Kann man die Datei nicht im Arbeitsspeicher erstellen, und wenn die Aufnahme fertig ist, dann auf die Festplatte speichern ?
Oder die erste Sekunde der Aufnahme auf der Festplatte speichern, und dann den Rest weil im Arbeitsspeicher hineinschreiben (puffern), wenn die Aufnahme fertig ist, dann den Inhalt des Ram´s auf die Festplatte mit dazu speichern ?


Also ihr wisst jetzt was ich will ! -- Den Dauer-Festplattenzugriff verhindern, indem man in den RAM schreibt (also als Puffer benutzen) !


Wie bekomme ich das hin ?
 
Zuletzt bearbeitet:
Ich hab jetzt mal statt den Pfad eine Variable angegeben.

Aber wie kann ich den Inhalt der Variable als Wav-Datei bei dem Beenden der Aufnahme auf die Festplatte (Pfad) schreiben, sodass es auch ne richtige Wav-Datei ist. (keine kaputte)
 
Zuletzt bearbeitet:
Ich weiß nicht, wie die Spezifikation einer WAV-Datei aussieht, auf jeden Fall muss sie aber die PCM-Header enthalten, wo eben festgeschrieben wird, welche Samplerate usw. verwendet wurde. Wenn Du die reinen Daten aus der Variablen verwendest, erhältst Du wohlmöglich eine RAW-Datei. Das ist prinzipiell auch kein Problem, wenn Du beim Verarbeiten weißt, welche Parameter für die Aufnahme verwendet worden sind.

Generell würde ich Dir jedoch empfehlen, nicht während der gesamten Aufnahme im RAM zu puffern. Da die Audiosignale unkomprimiert aufgenommen werden, schaufelt dieses Verfahren den Arbeitsspeicher schnell zu. Du solltest regelmäßig den Puffer in die Datei ausgeben, etwa wenn eine bestimmte Größe überschritten wird oder eine festgelegte Anzahl Sekunden aufgenommen wurde. Damit verhinderst Du, dass der Arbeitsspeicher immer knapper wird, musst aber auch nicht ständig auf die Platte schreiben.
 
Ja erstmal danke, aber ich hab ja mein Problem schon im zweiten Beitrag angegeben:

Ich hab jetzt mal statt den Pfad eine Variable angegeben.

Aber wie kann ich den Inhalt der Variable als Wav-Datei bei dem Beenden der Aufnahme auf die Festplatte (Pfad) schreiben, sodass es auch ne richtige Wav-Datei ist. (keine kaputte)

Der letzte Satz ist mein Problem.
 
Eine wave Datei zu erzeugen sollte kein Problem darstellen. Das habe ich sogar schon einmal gemacht. Das Dateiformat siehst du hier:

http://ccrma.stanford.edu/courses/422/projects/WaveFormat/

Ok ich habe noch eine kleine Hilfe für dich. Das ist der Code in VB.NET für mein Testprogramm. Das erzeugt ein wav Datei mit einer Frequenz von 2000 Hz und spielt es nachher ab:
In der Maske gibt man die Bits pro Sample und die Samplerate an. Wenn man Stereo hat, dann muss man es noch etwas umschreiben.

Imports System.io

Public Class Form1
Dim file As String = "C:\Temp\output.wav"
Dim bits As Integer
Dim samples As Integer
Dim length As Integer = 90

Private Sub btn_start_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_start.Click
bits = Integer.Parse(txt_bitspersample.Text)
samples = Integer.Parse(txt_samplerate.Text)

Dim stream As New FileStream(file, FileMode.Create)
Dim out As New BinaryWriter(stream)

out.Seek(44, SeekOrigin.Begin)

Dim pos As Double = 0
Dim frequency As Integer = 2000
Dim amplitude As Integer
Dim i As Double = 0

While pos < length
amplitude = (Math.Sin(pos * frequency) + 1) * (Math.Pow(2, bits) / 2 - 1)
pos += 1 / samples

If bits = 16 Then
Dim towrite As UInt16 = amplitude
out.Write(towrite)
Else
Dim towrite As Byte = amplitude
out.Write(towrite)
End If
End While

Dim filelength As Integer = out.Seek(0, SeekOrigin.Current)
Dim bytespersecond As Integer = samples * bits / 8
Dim blocksize As Integer = bits / 8

out.Seek(0, SeekOrigin.Begin)
out.Write(1179011410) 'RIFF
out.Write(filelength - 8)
out.Write(1163280727) 'WAVE
out.Write(544501094) 'fmt
out.Write(16)
out.Write(65537)
out.Write(samples)
out.Write(bytespersecond)
out.Write(bits * 65536 + blocksize)
out.Write(1635017060) 'DATA
out.Write(filelength - 44)

out.Close()

My.Computer.Audio.Play("C:\Temp\output.wav", AudioPlayMode.WaitToComplete)
End Sub

Public Function convert(ByVal toconvert As UInt16) As UInt16
Dim b1 As Byte = toconvert Mod 256
Dim b2 As Byte = Math.Floor(toconvert / 256)

Return b1 * 256 + b2
End Function

Public Function convert(ByVal toconvert As UInt32) As UInt32
Dim b1 As Byte = toconvert Mod 256
Dim b2 As Byte = Math.Floor(toconvert / 256) Mod 256
Dim b3 As Byte = Math.Floor(toconvert / 65536) Mod 256
Dim b4 As Byte = Math.Floor(toconvert / 16777216) Mod 256

Return b1 * 16777216 + b2 * 65536 + b3 * 256 + b4
End Function
End Class
 
Zuletzt bearbeitet:
Zurück
Oben