Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TMemoryStream - Instanzbildung scheitert? (https://www.delphipraxis.net/145793-tmemorystream-instanzbildung-scheitert.html)

Flips 8. Jan 2010 14:52


TMemoryStream - Instanzbildung scheitert?
 
Hi,

ich habe eine Prozedur aus dem Netz, welche einen MemoryStream nutzt. Dieser wurde lokal deklariert, am Anfang der Prozedur erzeugt und am Schluss freigegeben, so wie das sein sollte.
Jetzt bräuchte ich den Inhalt des Memorystream zur gesamten Laufzeit. Also dachte ich gut, deklarier ich ihn global (Habs als Attribut des Forms und als globale Variable der Unit probiert) und setze die Create (Free) Methode ins OnCreate (OnDestroy) des Forms.
Gesagt getan, Programm gestartet. Sobald ich jedoch dann den Stream benutzen will (bspw: Write), erscheint eine Zugriffsverletzung, welche ich früher zu genüge hatte, als ich nicht wusste, dass Objekte erzeugt werden müssen.

Doch wieso bekomme ich hier einen solchen Fehler, obwohl ich doch im OnCreate des Forms (was logischerweise auch ausgeführt wird, wenn ich das Form ja sehe) die Instanz erstelle?

Wie gesagt, wenn ich lokal in der Funktion bleibe dann klappt alles.

Hoffe Ihr könnt mir helfen.

Lg, Flips

Luckie 8. Jan 2010 14:56

Re: TMemoryStream - Instanzbildung scheitert?
 
Ohne Code wird das nichts. Theoretisch sollte es funktionieren, wenn die Variable als Feld der Formularklasse deklariert ist.

Flips 8. Jan 2010 15:04

Re: TMemoryStream - Instanzbildung scheitert?
 
Ich habs jetzt mal quick'n'dirty per global Variable in der neuen Anwendung gemacht, da klappts auch...Aber keine Ahnung, wieso folgender Code etwas am Stream selbst ändert. Der Code ist übrigends dieser hier, nur für meine Zwecke ein wenig geändert.

Delphi-Quellcode:
 private
    FMS : TMemoryStream;
 public
    property MS : TMemoryStream read FMS write FMS;
  end;

[...]

procedure TForm2.GenerateSound(FromFQ, ToFQ, FQJumps, FQDuration: Integer; Volume: TVolumeLevel);
  {writes tone to memory and plays it}
var
  WaveFormatEx: TWaveFormatEx;
  MS: TMemoryStream;
  i, TempInt, DataCount, RiffCount, Frequency: integer;
  SoundValue: byte;
  w: double; // omega ( 2 * pi * frequency)
const
  Mono: Word = $0001;
  SampleRate: Integer = 44100; // 8000, 11025, 22050, or 44100
  RiffId: string = 'RIFF';
  WaveId: string = 'WAVE';
  FmtId: string = 'fmt ';
  DataId: string = 'data';
begin
  with WaveFormatEx do
  begin
    wFormatTag := WAVE_FORMAT_PCM;
    nChannels := Mono;
    nSamplesPerSec := SampleRate;
    wBitsPerSample := $0008;
    nBlockAlign := (nChannels * wBitsPerSample) div 8;
    nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
    cbSize := 0;
  end;

  with FMS do
  begin
    {Calculate length of sound data and of file data}
    DataCount := (ceil((ToFQ-FromFQ)/FQJumps) * FQDuration * SampleRate) div 1000; // sound data
    RiffCount := Length(WaveId) + Length(FmtId) + SizeOf(DWORD) +
      SizeOf(TWaveFormatEx) + Length(DataId) + SizeOf(DWORD) + DataCount; // file data
    {write out the wave header}

    Write(RiffId[1], 4); // 'RIFF' -> ########################## Hier krachts
    Write(RiffCount, SizeOf(DWORD)); // file data size
    Write(WaveId[1], Length(WaveId)); // 'WAVE'
    Write(FmtId[1], Length(FmtId)); // 'fmt '
    TempInt := SizeOf(TWaveFormatEx);
    Write(TempInt, SizeOf(DWORD)); // TWaveFormat data size
    Write(WaveFormatEx, SizeOf(TWaveFormatEx)); // WaveFormatEx record
    Write(DataId[1], Length(DataId)); // 'data'
    Write(DataCount, SizeOf(DWORD)); // sound data size
    {calculate and write out the tone signal} // now the data values
    Frequency := FromFQ;
    while Frequency <= ToFQ do
    begin
      w := 2 * Pi * Frequency; // omega
      Memo1.Lines.Add('Schreibe ' +inttostr(Frequency)+'Hz');
      for i := 0 to ((FQDuration * SampleRate) div 1000) - 1 do
      begin
        SoundValue := 127 + trunc(Volume * sin(i * w / SampleRate)); // wt = w * i / SampleRate
        Write(SoundValue, SizeOf(Byte));
      end;
      inc(Frequency,FQJumps);
    end;

  end;
end;


procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FMS.Free;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
FMS := TMemoryStream.Create;
end;

Luckie 8. Jan 2010 15:05

Re: TMemoryStream - Instanzbildung scheitert?
 
Zitat:

Zitat von Flips
Aber keine Ahnung, wieso folgender Code etwas am Stream selbst ändert.

Das verstehe ich jetzt nicht. Klappt es oder klappt es nicht?

Flips 8. Jan 2010 15:08

Re: TMemoryStream - Instanzbildung scheitert?
 
Der Code oben funktioniert so nicht.
Wenn ich jetzt ein neues Programm erstelle wo nix drin ist, nur ein MemoryStream als globale Variable (respektive Feld), den im OnCreate erstelle un dann in ner ButtonClick-Methode was damit mache, dann klappt das auch.

Deshalb wundert es mich, dass es nicht auch in oben gepostetem Code funktioniert...

sirius 8. Jan 2010 15:25

Re: TMemoryStream - Instanzbildung scheitert?
 
Wie kracht es denn?

(In solchen Sachen besser nicht With verwenden. Wer weis, vielleicht wird hier ein ganz anderes write aufgerufen.)

Flips 8. Jan 2010 15:52

Re: TMemoryStream - Instanzbildung scheitert?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habs mal trotz with noch über die Klasse selbst aufgerufen, gleiches Ergebnis.
Es kracht so, wies bei ner Zugriffsverletzung halt kracht^^, siehe Bild.

wicht 8. Jan 2010 16:38

Re: TMemoryStream - Instanzbildung scheitert?
 
Delphi-Quellcode:
var
  ...
  MS: TMemoryStream; /// Ist hier der Bock ??? ///
  ...
const
Das könnte den Crash aus dem letzten Screenshot erklären.

HTH

Muetze1 8. Jan 2010 16:50

Re: TMemoryStream - Instanzbildung scheitert?
 
Klassenmember unter eine Property veröffentlichen (MS) und dann eine lokale Variable deklarieren gleichen Typs und Namens (MS) ist schon sehr schlecht. Da zeigt es sich mal wieder, dass man lokale Variable vllt. ein Präfix geben sollte...

Flips 8. Jan 2010 17:15

Re: TMemoryStream - Instanzbildung scheitert?
 
Ich Idiot.
Das war keine Absicht, ich hab es einfach nur nicht gesehen -.-
Hab total vergessen, die lokale Deklaration zu löschen -.-

Danke dir...Mannmannmann das kommt davon, wenn man mal Tee statt kaffee trinkt...:-P


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz