![]() |
"bass.dll" Aufnahme an beliebiger Stelle im Stream
Hallo mal wieder,
ich bräuchte mal wieder einen kleinen Denkanstoß. Momentan programmiere ich ein kleines Diktiergerät und benutze dazu die bass.dll. Wenn jetzt der Nutzer etwas aufgenommen hat und merkt, dass er etwas ändern will, dann möchte ich, dass er an einer beliebigen Stelle die Aufnahme fortsetzen kann und der Rest der schon vorhandenen Aufnahme dann gelöscht/überschrieben wird. Bis jetzt habe ich die Aufnahmemodi "Ans Ende anhängen" und "Aufnahme überschreiben". Aber in die Aufnahme noch etwas einfügen, bzw. das was ich oben erläutert habe ist mir bisher noch nicht gelungen. Zwar kann ich einfach einen Teil des Streams überschreiben, aber wenn zum Beispiel die neue Aufnahme kürzer ist als die zuvor aufgenommene, dann hört man ja am Ende noch was von der alten Aufnahme. Um das Problem nicht zu haben müsste also erstmal der Teil des Streams, ab dem ich neu aufnehmen möchte, gelöscht werden. (1.Problem) Und um später noch Passagen einfügen zu können würde ich gerne den Teil des Streams ab dem die Passage eingeführt wird bis zum Ende des Streams in einen 2. Stream speichern, dann aus dem alten Stream löschen, die Passage aufnehmen und den kopierten Teil aus dem zweiten Stream danach wieder ans Ende ranhängen. (2.Problem) Bis jetzt klappt das aber noch gar nicht. Hier mal der Code, den ich bisher habe: (Der CopyFrom-Befehl erzeugt allerdings eine AV)
Delphi-Quellcode:
// Aufnahme je nach Aufnahmemodus
if OverwriteRadioButton.Checked = True then begin if WaveStream.Size > 0 then begin // alte Aufnahme löschen BASS_StreamFree(chan); WaveStream.Clear; end; // if end else if InsertRadioButton.Checked = True then begin if WaveStream.Size = 0 then begin end else begin WaveStream.Position := ProgressBar.Position; WaveStream.CopyFrom(BufStream, WaveStream.Position); end; end else if EndRadioButton.Checked = True then begin WaveStream.Position := WaveStream.Size; ProgressBar.Position := ProgressBar.Max; end; // if |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Aktualisierung:
Das Einfügen einer Passage habe ich jetzt alleine hinbekommen. Ich hatte copyfrom total falsch verstanden. Hier der aktualisierte Code bisher:
Delphi-Quellcode:
und dann beim Beenden der Aufnahme:
// Aufnahme je nach Aufnahmemodus
if OverwriteRadioButton.Checked = True then begin if WaveStream.Size > 0 then begin // alte Aufnahme löschen BASS_StreamFree(chan); WaveStream.Clear; end; // if end else if InsertRadioButton.Checked = True then begin if WaveStream.Size = 0 then begin end else begin WaveStream.Position := ProgressBar.Position; BufStream := TMemoryStream.Create; BufStream.CopyFrom(WaveStream, WaveStream.Size-WaveStream.Position); WaveStream.Position := ProgressBar.Position; end;
Delphi-Quellcode:
Ich muss jetzt noch rausfinden wie man Teile eines Streams löscht und schon hat sich der Thread von alleine erledigt ;)
if InsertRadioButton.Checked = True
then begin if WaveStream.Size = 0 then begin end else begin WaveStream.CopyFrom(BufStream, 0); FreeAndNil(BufStream); end; end; MfG |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Delphi-Quellcode:
So habe ich jetzt das Löschen des alten Parts, welcher übersprochen werden soll bewerkstelligt.
WaveStream.Position := ProgressBar.Position;
WaveStream.SetSize(WaveStream.Size-WaveStream.Position); Damit habe ich meinen eigenen Thread wohl selber beantwortet *gg* MfG Franz |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Hi, das Problem ist doch noch nicht gelöst :(
Wenn die Länge der zweiten Aufnahme größer ist als die des ursprünglich überschriebenen Streams, dann entsteht ein ganz hässliches Rauschen. Ich glaube dass das mit SetSize zusammenhängt. Hier der jetzige Code:
Delphi-Quellcode:
// Aufnahme je nach Aufnahmemodus
if WaveStream.Size = 0 then begin end else begin if Rec_Passage.Checked = True then begin try WaveStream.Position := GetPos; BufStream := TMemoryStream.Create; BufStream.CopyFrom(WaveStream, WaveStream.Size-WaveStream.Position); WaveStream.Position := GetPos; except FreeAndNil(BufStream); end; end else begin try WaveStream.Position := GetPos; WaveStream.SetSize(BASS_ChannelGetLength(rchan)-WaveStream.Position); except end; end; // if und beim Beenden der Aufnahme: if Rec_Passage.Checked = True then begin try WaveStream.CopyFrom(BufStream, 0); finally FreeAndNil(BufStream); end; end; // if Rec_Passage soll eigentlich eine neue Passage einfügen und Rec_Overwrite soll ab der Position an der man sich befindet alles überschreiben. Kann mir da vielleicht doch einer helfen? Und bei den Moderatoren möchte ich mich ganz herzlich für die ganzen Doppelposts entschuldigen. Werde ab jetzt die Edit-Funktion nutzen. Gruß, Duck |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Schau dir doch bei 3dLite den TStream Editor an denke das wird die unter umständen mehr helfen
Ohne kompletten Code was da nun passiert bei dir ist es schwer zu helfen. gruss Emil |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Nabend,
falls du meintest ich soll auf 3dlite.com schauen, dann muss ich leider sagen, dass man auf der Site momentan nicht viel findet ;) Desweiteren ist doch da der gesamte Code, welcher Relevant ist, da ich ja nur am Wavestream rumschnippel :p Das BASS_ChannelGetLength(rchan) muss btw durch ein Wavestream.Size ersetzt werden. Hast du evtl. noch andere Vorschläge? Viele Grüße, Franz |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
|
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Hm ne, das hat mir ausnahmsweise mal nicht geholfen..
Also momentan sieht es bei mir folgendermaßen aus: Callback-Routine:
Delphi-Quellcode:
Start der Aufnahme:
(* Callback *)
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
Delphi-Quellcode:
(* Aufnahme Start *)
procedure TFormular.StartRecording; var vol: Float; i: Integer; Flag: DWord; begin // Aufnahme je nach Aufnahmemodus if WaveStream.Size = 0 then begin end else begin if Rec_Passage.Checked = True then begin try // ín aufgenommenen Stream eine Passage nach aktueller // Position einfügen except end; end else begin (*WaveStream.Position := GetPos; Edit1.Text := IntToStr(WaveStream.Position); BufStream := TMemoryStream.Create; BufStream.CopyFrom(WaveStream, WaveStream.Position); BASS_ChannelStop(chan); BASS_ChannelStop(rchan); BASS_StreamFree(chan); BASS_StreamFree(rchan); WaveStream := nil; WaveStream := TMemoryStream.Create; WaveStream.CopyFrom(BufStream, 0); FreeAndNil(BufStream);*) // alles nach aktueller Position löschen und dort Aufnahme // fortführen try except end; end; // if end; // 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; 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 Beenden der Aufnahme:
Delphi-Quellcode:
(* Stop recording *)
procedure TFormular.StopRecording; var i: integer; begin BASS_ChannelStop(rchan); // 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; if Rec_Passage.Checked = True then begin try finally end; end; // if // 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 (* RecordButtonClick || Start Aufnahme *) procedure TFormular.RecExecute(Sender: TObject); begin if BASS_ChannelIsActive(rchan) = BASS_Active_Stopped then // Aufnahme starten begin if BASS_ChannelIsActive(chan) <> BASS_Active_Stopped then begin BASS_ChannelStop(chan); //ProgressBar.Position := ProgressBar.Max; StartRecording; end else begin //ProgressBar.Position := ProgressBar.Max; StartRecording; end; // if RecToggleStatus(8); end else if BASS_ChannelIsActive(rchan) = BASS_Active_Playing then // Aufnahme beenden begin StopRecording; RecToggleStatus(3); end; end; //procedure RecExecute Es kann doch eigentlich nich so schwer sein beim Start der Aufnahme vom vorhandenen Stream alles aber der aktuellen Position des Streams zu löschen und dort die Aufnahme fortzuseten, oder doch? MfG Ducksoul |
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Keiner ne Idee? :(
|
Re: "bass.dll" Aufnahme an beliebiger Stelle im St
Hallo,
das sollte ja nicht so schwer sein... RecPos := ** Position wo weiter aufgenommen werden soll ** // 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; ** weiter aufnehmen... Habs jetzt zwar nicht ausprobiert, aber sollte eigentlich funktionieren... Anmerkung: :warn: Beim Start der Aufnahme schreibst du anscheinend immer wieder an die aktuelle Position den Wave-Header... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:26 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