![]() |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
So sieht die abgeänderte Version aus. Jetzt wird der Header nicht jedes mal neu geschrieben. Das war mir heute morgen schon aufgefallen, aber das abzuändern hatte leider nichts gebracht.
Das Problem mit dem Rauschen besteht aber leider immernoch, komischerweise nicht immer, sondern nur manchmal. Kann es sein, dass aus mir unbekannten Gründen der Stream manchmal vorhandene Daten überschreibt und daher das Rauschen entsteht? Da ich keine Ahnung habe woran das Verhalten überhaupt liegen kann, weiß ich nichmal wie ich das Problem angehen kann :(
Delphi-Quellcode:
Danke trotzdem,
(* Aufnahme Start *)
procedure TFormular.StartRecording; var vol: Float; i, RecPos: Integer; Flag: DWord; begin if WaveStream.Size = 0 then begin // Header für WAV-File generieren with WaveHdr do begin riff := 'RIFF'; len := 36; cWavFmt := 'WAVEfmt '; dwHdrLen := 16; wFormat := 1; wNumChannels := 2; dwSampleRate := 44100; wBlockAlign := 4; dwBytesPerSec := 176400; wBitsPerSample := 16; cData := 'data'; dwDataLen := 0; end; // with WaveStream.Write(WaveHdr, SizeOf(WAVHDR)); i := 0; end else begin if Rec_Overwrite.Checked = True then begin // hier ab aktueller Position Aufnahme fortsetzen (*WaveStream.Seek(GetPos, soFromBeginning); if WaveStream.Position < SizeOf(WaveHDR) then WaveStream.Seek(SizeOf(WaveHDR)+1, soFromBeginning); WaveStream.SetSize(WaveStream.Position); WaveStream.Seek(0, soFromEnd); Edit1.Text := IntToStr(WaveStream.Size); *) RecPos := GetPos; // Zwischenspeicher anlegen BufStream := TMemoryStream.Create; BufStream.SetSize(RecPos); // Wavedaten in Zwischenspeicher kopieren Move(WaveStream.Memory^,BufStream.Memory^,RecPos); // WaveStream abschneiden WaveStream.SetSize(RecPos); // Wavedaten rückkopieren Move(BufStream.Memory^,WaveStream.Memory^,RecPos); BufStream.Free; // Position setzen WaveStream.Position := RecPos; end; // if if Rec_Passage.Checked = True then begin // hier an aktueller Position Passage einfügend end; // if end; // if vol := RecordPegelBar.Position/100; while BASS_RecordSetInput(i, BASS_INPUT_OFF, vol) do i := i + 1; // ---LoWord-- ----HiWord---- Flag := MakeLong(c16BitAudio, cRecordingTime); // Aufnahmebeginn @ 44100hz 16-bit stereo rchan := BASS_RecordStart(cSamplerate, cNumChannels, Flag, @RecordingCallback, nil); if rchan = 0 then begin MessageDlg('Aufnahme konnte nicht gestartet werden!', mtError, [mbOk], 0); WaveStream.Clear; end; end; // procedure StartRecording Duck |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Wann rauscht was wo? :gruebel:
|
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Wegen Nicht-Beachtung gelöscht.
|
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Wenn du was in deinen Wave-Stream einfügen willst nimmst du für diesen Modus am einfachsten einen neuen Stream in der Callback-Funktion.
Etwa so, ohne Funktionsgarantie... Einfügeposition merken InsertStream anlegen und in Callback verwenden nach Aufnahmeende Zwischenspeicher anlegen WaveStream bis zur Einfügeposition in Zwischenspeicher schreiben InsertStream in Zwischenspeicher anhängen Rest des Wavestreams in Zwischenspeicher anhängen WaveStream Größe neu setzen Zwischenspeicher in Wavestream rückkopieren Länge im Wavehader anpassen function RecordingCallback.... if Rec_Passage.Checked then Formular.InsertStream.Write(buffer^, length) else Formular.WaveStream.Write(buffer^, length); ... procedure TFormular.StartRecording; ... if Rec_Passage.Checked then InsertPos := GetPos; InsertStream := TMemoryStream.Create; end if; ... procedure TFormular.StopRecording; ... if Rec_Passage.Checked then begin BufStream := TMemoryStream.Create; BufStream.Write(WaveStream.Memory^,InsertPos); BufStream.Write(InsertStream.Memory^,InsertStream. Size); BufStream.Write(PByteArray(WaveStream.Memory)^[InsertPos],WaveStream.Size-InsertPos); WaveStream.SetSize(BufStream.Size); Move(BufStream.Memory^,WaveStream.Memory^,BufStrea m.Size); BufStream.Free; InsertStream.Free; end; // WAV-Header komplettieren WaveStream.Position := 4; i := WaveStream.Size - 8; .... So ähnlich muss das klappen ohne das was rauscht... Und ich geh jetzt auf den Federnball... |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Guten Morgen,
also mein Code sieht nun wie folgt aus, aber das Rauschen besteht immernoch. Aber mir ist eingefallen woran es eventuell liegen könnte: (* Angenommen ich nehme was auf, dann wird am Ende ja der Waveheader komplettiert. Nehme ich was neues auf, dann wird die vorige Datei mit kompletten Waveheader genommen und der Waveheader am Ende nochmal komplettiert und so weiter und sofort. Könnte das die Ursache sein? *) Edit: Ich habe es jetzt so gelöst, dass der WaveStream ohne komplettierten Header in einen Zwischenspeicher BufStream2 gespeichert wird und beim Zusammenführen dann aus diesem gelesen wird und nicht aus dem WaveStream mit komplettierten Header.(siehe Code) Das Problem besteht trotzdem noch... Wenn ja fragt sich dann nur noch, wie ich den Waveheader dann jedesmal zurückkomplettiere, um es mal so auszudrücken ^^
Delphi-Quellcode:
Edit2:
(******************************************************************************)
(* CallBack-Routine *) (******************************************************************************) (* Callback WaveStream *) function RecordingCallback(Handle: HRECORD; buffer: Pointer; length, user: DWord): boolean; stdcall; begin // Kopiere neuen Bufferinhalt in den Memory Buffer Formular.WaveStream.Write(buffer^, length); // Weiteres Aufnehmen erlauben Result := True; end; // function Callback (* Callback InsertStream *) function RecordingInsertCallback(Handle: HRECORD; buffer: Pointer; length, user: DWord): boolean; stdcall; begin // Kopiere neuen Bufferinhalt in den Memory Buffer Formular.InsertStream.Write(buffer^, length); // Weiteres Aufnehmen erlauben Result := True; end; (******************************************************************************) (* Start und Stop Aufnahme *) (******************************************************************************) (* Aufnahme Start *) procedure TFormular.StartRecording; var vol: Float; i: Integer; Flag: DWord; begin InsertRec := False; vol := RecordPegelBar.Position/100; while BASS_RecordSetInput(i, BASS_INPUT_OFF, vol) do i := i + 1; if WaveStream.Size = 0 then begin // Header für WAV-File generieren with WaveHdr do begin riff := 'RIFF'; len := 36; cWavFmt := 'WAVEfmt '; dwHdrLen := 16; wFormat := 1; wNumChannels := 2; dwSampleRate := 44100; wBlockAlign := 4; dwBytesPerSec := 176400; wBitsPerSample := 16; cData := 'data'; dwDataLen := 0; end; // with WaveStream.Write(WaveHdr, SizeOf(WAVHDR)); i := 0; // ---LoWord-- ----HiWord---- Flag := MakeLong(c16BitAudio, cRecordingTime); // Aufnahmebeginn @ 44100hz 16-bit stereo rchan := BASS_RecordStart(cSamplerate, cNumChannels, Flag, @RecordingCallback, nil); end else begin InsertRec := True; if Rec_Overwrite.Checked = True then begin try InsertPos := GetPos; InsertStream := TMemoryStream.Create; // ---LoWord-- ----HiWord---- Flag := MakeLong(c16BitAudio, cRecordingTime); // Aufnahmebeginn @ 44100hz 16-bit stereo rchan := BASS_RecordStart(cSamplerate, cNumChannels, Flag, @RecordingInsertCallback, nil); except InsertStream.Free; end; // try end; // if if Rec_Passage.Checked = True then begin // hier an aktueller Position Passage einfügen end; // if end; // if if rchan = 0 then begin MessageDlg('Aufnahme konnte nicht gestartet werden!', mtError, [mbOk], 0); WaveStream.Clear; end; end; // procedure StartRecording (* Stop recording *) procedure TFormular.StopRecording; var i: integer; begin BASS_ChannelStop(rchan); if InsertRec = True then begin if Rec_Overwrite.Checked = True then begin // hier Streams zusammenfügen /nach aktueller Posi fortfahren try BufStream := TMemoryStream.Create; BufStream2.Seek(0, soFromBeginning); BufStream.Write(BufStream2.Memory^, InsertPos); BufStream.Write(InsertStream.Memory^, InsertStream.Size); //BufStream.Write(PByteArray(WaveStream.Memory)^[InsertPos],WaveStream.Size-InsertPos); WaveStream.SetSize(BufStream.Size); Move(BufStream.Memory^, WaveStream.Memory^, BufStream.Size); finally FreeAndNil(BufStream); FreeAndNil(BufStream2); FreeAndNil(InsertStream); end; // try end; // if if Rec_Passage.Checked = True then begin // hier BufStream nach neuer Passage anfügen end; // if end; // if try BufStream2 := TMemoryStream.Create; BufStream2.CopyFrom(WaveStream, 0); except FreeAndNil(BufStream2); end; // try // WAV-Header komplettieren WaveStream.Position := 4; i := WaveStream.Size - 8; WaveStream.Write(i, 4); i := i - $24; WaveStream.Position := 40; WaveStream.Write(i, 4); WaveStream.Position := 0; // Stream für aufgenomme Daten kreieren chan := BASS_StreamCreateFile(True, WaveStream.Memory, 0, WaveStream.Size, 0); if chan <> 0 then begin //??? end else begin MessageDlg('Fehler beim Erstellen eines Streams aus der Aufnahme!', mtError, [mbOk], 0); end; // if end; // procedure StopRecording An folgenden Sachen liegt es denk ich mal nich, aber der Vollständigkeit halber will ich sie trotzdem ma noch reinstellen.
Delphi-Quellcode:
(* Update der Progressbar *)
procedure TFormular.RecordTimerTimer(Sender: TObject); var t, t2: integer; begin ProgressBar.OnChange := nil; ProgressBar.Position := Round((BASS_ChannelGetPosition(chan, BASS_POS_BYTE) / BASS_ChannelGetLength(chan, BASS_POS_BYTE)) * 100); ProgressBar.OnChange := ProgressBarChange; if (chan <> 0) then begin t := Round(BASS_ChannelBytes2Seconds(chan, BASS_ChannelGetPosition(chan, BASS_POS_BYTE))); t2 := Round(BASS_ChannelBytes2Seconds(chan, BASS_ChannelGetLength(chan, BASS_POS_BYTE))); progresstimeLabel.Caption := Format('%.2d:%.2d',[t Div 60, t Mod 60]); completetimeLabel.Caption := Format('%.2d:%.2d',[t2 Div 60, t2 Mod 60]); end; end; // procedure RecordTimerTimer (* Position via ProgressBar ändern *) procedure TFormular.ProgressBarChange(Sender: TObject); var Bool: Boolean; begin Bool := BASS_ChannelIsActive(chan) = BASS_ACTIVE_Playing; if Bool then BASS_ChannelPause(chan); BASS_ChannelSetPosition(chan, ProgressBar.Position * BASS_ChannelGetLength(chan, BASS_POS_BYTE) div 100, BASS_POS_BYTE); if Bool then BASS_ChannelPlay(chan, False); end; // procedure ProgressBarChange (* Position des Chans ermitteln *) function TFormular.GetPos: Integer; begin Result := Round((ProgressBar.Position * BASS_ChannelGetLength(chan, BASS_POS_BYTE)) / 100); end; // function GetPos |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Der Sinn von BufStream2 erschliesst sich mir nicht... :gruebel:
Wenn du der Meinung bist das dein "rauschen" an der Aufnahme mit dem Wavestream liegt, wieso nimmst du dann nicht einen Stream zum "recorden" und den anderen für dein Ergebnis. So hast du nur eine Callback und immer einen leeren Stream zum aufnehmen.Bei Aufnahmeende kannst du mit den Recordingdaten machen was du willst...anhängen, einfügen, ... Und danach korrigierst du den Waveheader im Ergebnis-Stream. :hi: |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Also das mit dem BufStream2 war nur ein Test in meiner Not. Inzwischen habe ich das auch schon wieder geändert.
Ob das Rauschen am WaveStream liegt weiß ich nich genau, da ich den Fehler nicht eingrenzen kann, aber das muss es ja sein. Ich hoffe, dass dein Tipp mich jetzt weiterbringt, aber große Hoffnung hab ich nicht mehr. Und morgen muss ich eigentlich fertig werden mit dem Projekt... Oh man... ^^ MfG |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Nabend,
ich muss mich leider nochmal melden. Ich weiß einfach nicht woran der Fehler liegen kann. Falls interesse besteht würde ich auch mal den kompletten Source an jemanden schicken, falls das einer mal testen möchte... Das Programm muss diese Woche fertig werden und ich bekomm einfach den Fehler nicht in den Griff.... Hier der aktuelle Code:
Delphi-Quellcode:
(* Callback RecStream *)
function RecordingCallback(Handle: HRECORD; buffer: Pointer; length, user: DWord): boolean; stdcall; begin // Kopiere neuen Bufferinhalt in den Memory Buffer Formular.RecStream.Write(buffer^, length); // Weiteres Aufnehmen erlauben Result := True; end; // function Callback WaveStream (******************************************************************************) (* Aufnahme Beginnen *) procedure TFormular.StartRecording; var i: Integer; Flag: DWord; begin InsertPos := Round((ProgressBar.Position * BASS_ChannelGetLength(chan, BASS_POS_BYTE)) / 100);; RecStream := TMemoryStream.Create; // ---LoWord-- ----HiWord---- Flag := MakeLong(c16BitAudio, cRecordingTime); // Aufnahmebeginn @ 44100hz 16-bit stereo rchan := BASS_RecordStart(cSamplerate, cNumChannels, Flag, @RecordingCallback, nil); // Prüfen, ob Aufnahme erfolgreich gestartet if rchan = 0 then begin MessageDlg('Aufnahme konnte nicht gestartet werden!', mtError, [mbOk], 0); RecStream.Clear; end; // if rchan = 0 end; // procedure StartRecording (******************************************************************************) (* Aufnahme Beenden *) procedure TFormular.StopRecording; var i: integer; HeaderStream, InsertBufStream: TMemoryStream; begin // Aufnahmekanal stoppen BASS_ChannelStop(rchan); try // Header für WAV-File generieren with WaveHdr do begin wNumChannels := 1; wBitsPerSample := 16; wBlockAlign := wNumChannels * (wBitsPerSample div 8); dwSampleRate := 44100; dwBytesPerSec := dwSampleRate * wBlockAlign; riff := 'RIFF'; len := 36; cWavFmt := 'WAVEfmt '; dwHdrLen := 16; wFormat := 1; cData := 'data'; dwDataLen := 0; end; // with // Header in Aufnahmestream schreiben HeaderStream := TMemoryStream.Create; HeaderStream.Write(WaveHdr, SizeOf(WAVHDR)); i := 0; if WaveStream.Size = 0 then begin // Aufnahme ohne Header zwischenspeichern BufStream := TMemoryStream.Create; RecStream.Seek(0, soFromBeginning); BufStream.Write(RecStream.Memory^, RecStream.Size); WaveStream.Write(HeaderStream.Memory^, HeaderStream.Size); WaveStream.Write(RecStream.Memory^, RecStream.Size); end else begin InsertBufStream := TMemoryStream.Create; BufStream.Seek(0, soFromBeginning); InsertBufStream.Write(HeaderStream.Memory^, HeaderStream.Size); InsertBufStream.Write(BufStream.Memory^, InsertPos-HeaderStream.Size); InsertBufStream.Write(RecStream.Memory^, RecStream.Size); WaveStream.SetSize(InsertBufStream.Size); Move(InsertBufStream.Memory^, WaveStream.Memory^ , InsertBufStream.Size); Edit1.Text := IntToStr(InsertPos); BufStream.SetSize(InsertBufStream.Size - HeaderStream.Size); InsertBufStream.Seek(HeaderStream.Size, soFromBeginning); BufStream.Write(InsertBufStream.Memory^, InsertBufStream.Size - HeaderStream.Size); InsertBufStream.Free; end; (* if Rec_Overwrite.Checked = True then begin // hier Streams zusammenfügen /nach aktueller Posi fortfahren try BufStream := TMemoryStream.Create; BufStream.CopyFrom(WaveStream, InsertPos); BufStream.CopyFrom(RecStream,0); WaveStream.Position := 0; WaveStream.CopyFrom(BufStream, 0); finally FreeAndNil(BufStream); end; // try end; // if Rec_Overwrite.Checked *) finally RecStream.Free; HeaderStream.Free; end; (*if Rec_Passage.Checked = True then begin // hier BufStream nach neuer Passage anfügen try BufStream := TMemoryStream.Create; BufStream.Write(WaveStream.Memory^, InsertPos); BufStream.Write(InsertStream.Memory^, InsertStream.Size); BufStream.Write(PByteArray(WaveStream.Memory)^[InsertPos],WaveStream.Size-InsertPos); WaveStream.SetSize(BufStream.Size); Move(BufStream.Memory^, WaveStream.Memory^, BufStream.Size); finally FreeAndNil(BufStream); FreeAndNil(InsertStream); end; // try end; // if Rec_Passage.Checked end; // if InsertRec *) // WAV-Header komplettieren WaveStream.Position := 4; i := WaveStream.Size - 8; WaveStream.Write(i, 4); i := i - $24; WaveStream.Position := 40; WaveStream.Write(i, 4); WaveStream.Position := 0; // Wiedergabestream kreieren chan := BASS_StreamCreateFile(True, WaveStream.Memory, 0, WaveStream.Size, 0); // Prüfen, ob Wiedergabestream erfolgreich erstellt if chan = 0 then MessageDlg('Fehler beim Erstellen eines Streams aus der Aufnahme!', mtError, [mbOk], 0); end; // procedure StopRecording Viele Grüße |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Also kann mir keiner mit dem Problem helfen, oder zumindest ahnen woran der Fehler jetzt liegt?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz