Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Darstellung wie in Audioeditor (https://www.delphipraxis.net/52908-darstellung-wie-audioeditor.html)

igel457 6. Sep 2005 16:15


Darstellung wie in Audioeditor
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,

vielleicht kennt ihr so Audio-Editoren wie den Nero Wave Editor. Die Stellen die Wave-Datei ja komplett als "Visualisierung" dar.

Frage: Wie kriege ich das mit der Bass.dll hin, und schreibe diese "Visualisierung" auf ein Bitmap?
(Es soll nur so eine Art Thumbnail sein.)

Ich habe es so versucht:
Delphi-Quellcode:
function TForm1.GeneratePeaks(height,width:integer;stream:HStream):TBitmap;
var i,len,r,l,ypos,xpos:integer;
var WaveData : TWaveData;
begin
  result := TBitmap.Create;
  result.Height := height;
  result.Width := width;
  for len := 0 to bass.BASS_StreamGetLength(stream) do
  begin
    BASS_ChannelSetPosition(stream,len);
    BASS_ChannelGetData(stream, @WaveData, 2048);
    for i := 0 to 255 do
    begin
       R := SmallInt(Loword(WaveData[i * 1]));
       L := SmallInt(HIword(WaveData[i * 1]));
       YPos := Trunc(((R + L) / (2 * 65535)) * 1);
       xpos := trunc(len * (width / (BASS_StreamGetLength(stream))));
       result.Canvas.LineTo(xpos,ypos-10);
    end;
  end;
end;
YPos ist irgendwie immer 0! :gruebel:

Danke für eure Antworten.

shmia 6. Sep 2005 16:35

Re: Darstellung wie in Audioeditor
 
Du multiplizierst ja auch mit einer Variablen "l", die nirgends gesetzt wurde!
Du musst die Audio-Anzeige etwas anderst angehen.
Wenn mehr als ein Sample an einer Stelle dargestellt werden soll, dann musst du über mehrere Samples jeweils den minimalen und maximalen Wert ermitteln:
Dann zeichnest du eine Linie unter Verwendung von MovoTo und LineTo.
Delphi-Quellcode:
// YScale:double
// YScale = - 32768 / 100;  // max. Wert entspricht 100 Pixeln
MovoTo(xpos, Yoffset+ YScale * Ymin);
LineTo(xpos, YOffset+ YScale * YMax);
Ausserdem:
du versucht auch gleich beide Stereokanäle zu addieren und den Durchschnitt zu bilden.
Entweder zeichnest du jeden Kanal extra, oder du ermittelst getrennt für den L und R Kanal di minimalen
und maximalen Werte über mehrere Samples.
Dann hast du 2 Minima und 2 Maxima. Daraus wird ein Minimum und ein Maximum gebildet und das wird gezeichnet.
Hier kann man evtl. mit verschiedenen Farben die Unterschiede zwischen L & R Kanal hervorheben.

igel457 6. Sep 2005 16:53

Re: Darstellung wie in Audioeditor
 
Hallo.
Erstmal danke dür die Antwort, aber:
1. Das ist keine Variable | das ist 1 (EINS). (Wenn du es nicht glaubst kopiere es nach Word, oder sonstwo.)
Blödes Courier New :-D .
2. Das mit den Kanälen, das machen sie auch so in den Examples von Bass.

Frage: Wie stellst du dir das mit dem minimal und maximalwert vor?

Luckie 6. Sep 2005 16:58

Re: Darstellung wie in Audioeditor
 
Zitat:

Zitat von igel457
1. Das ist keine Variable | das ist 1 (EINS).

Das ist ja noch schlimmer. :wall: Darf man fragen, warum du mit eins multiplizierst?

igel457 6. Sep 2005 17:00

Re: Darstellung wie in Audioeditor
 
Das waren vorher andere werte. (Nur zum debugen)

shmia 6. Sep 2005 17:08

Re: Darstellung wie in Audioeditor
 
Zitat:

Zitat von igel457
Frage: Wie stellst du dir das mit dem minimal und maximalwert vor?

Folgendes Code Schnipsel ermittelt den minimal und maximalwert.
Es ist leicht, dies gleich für beide Kanäle zu tun.
Delphi-Quellcode:
YMin := 0;
YMax := 0;
for i := 0 to sample_count-1 do
begin
   Ywert := SmallInt(Loword(WaveData[i+ XPos*sample_count]));
   if YWert > YMax then
      YMax := YWert
   else if YWert < YMin then
      YMin := YWert;
end;

igel457 6. Sep 2005 18:38

Re: Darstellung wie in Audioeditor
 
Ich weiß irgendwie nicht so viel damit anzufangen.

Warum genau benötige ich einen Minimal und einen Maximalwert?

Ich hatte das eigentlich so vor:

Steppe das ganze Lied durch, bekomme Wave Data;
Steppe WaveData durch, zeichne es auf ein Bitmap.

Kannst du das nochmal genau erläutern?

shmia 6. Sep 2005 18:47

Re: Darstellung wie in Audioeditor
 
Zitat:

Zitat von igel457
Warum genau benötige ich einen Minimal und einen Maximalwert?

Ich hatte das eigentlich so vor:

Steppe das ganze Lied durch, bekomme Wave Data;
Steppe WaveData durch, zeichne es auf ein Bitmap.

Kannst du das nochmal genau erläutern?

Das Lied dauert z.B. 3 Minuten und hat 16000 Samples/sekunde.
Das sind dann 3*60*16000 = 2880000 verschiedene Werte.
Es ist klar, dass du das niemals direkt anzeigen kannst.
Angenommen dein nutzbares Display ist 1000 Pixel breit.
Dann muss du 2880000 / 1000 = 2880 Samples in einer senkrechten Linie darstellen.
Du suchst also innerhalb von 2880 Samples jeweils den minimalen und maximalen Wert.
Dieser Min-Max-Wert wird also stellvertretend für 2880 Einzelwerte gezeichnet.

igel457 6. Sep 2005 19:59

Re: Darstellung wie in Audioeditor
 
Achso!
Jetzt verstehe ich das genau!
Hört sich gut an.

Ich habe nur momentan das Problem, das der Minimale und der Maximale wert eines Samples komischerweise immer gleich ist, dazu habe ich die Werte mal in einer TIntegerList Gespeichert Hier im Forum suchenTIntederlist:

Delphi-Quellcode:
function TForm1.GeneratePeaks(height,width:integer;stream:HStream):TBitmap;
var i,len,r,l,ypos,xpos,ymax,ymin:integer;
var WaveData : TWaveData;
    liste :TIntegerList;
begin
  liste := TIntegerlist.Create;
  result := TBitmap.Create;
  result.Height := height;
  result.Width := width;
  for len := 0 to bass.BASS_StreamGetLength(stream) div 5000 do //div 5000 weil es sonst zu lange dauert
  begin
    BASS_ChannelSetPosition(stream,len*5000);
    BASS_ChannelGetData(stream, @WaveData, 2048);
    ymax := 0;
    ymin := 0;
    for i := 1 to 255 do
    begin
      Ypos := SmallInt(Loword(WaveData[i]));
      if Ypos > YMax then
        YMax := Ypos
      else if Ypos < YMin then
        YMin := Ypos;
    end;
    liste.Add(ymax div 100); //werte etwas kleiner machen
    liste.Add(ymin div 100); //werte etwas kleiner machen
  end;
  for i := 0 to liste.Count -1 do
    listbox1.Items.Add(inttostr(liste.Item[i]));
end;
Bass.dll hat geschrieben:
Zitat:

.
.
.
307
-276
307
-276
307
-276
307
-276
307
-277
307
-276
307
-276
307
-276
307
-276
.
.
.

christian.noeding 6. Sep 2005 21:48

Re: Darstellung wie in Audioeditor
 
Hi! Ich habe mal etwas weitergeproggt, da es für mich ebenfalls sehr interessant ist (ich habs nämlich selber nicht hinbekommen :-/)

Ich gehe wie folgt vor:

1) Laden einer Audiodatei mit Bass.dll:
Delphi-Quellcode:
Channel := BASS_StreamCreateFile(FALSE, PChar('c:\musik.mp3'), 0, 0, 0);
2) Abspielen der MP3:
Delphi-Quellcode:
  BASS_ChannelPlay(Channel, False);
3) In zwei Paintboxes für rechten und linken Kanal die Audiowave-Form anzeigen (noch nicht zu früh freuen):
Delphi-Quellcode:
procedure TMainForm.Button17Click(Sender: TObject);
var
  i,j, pos,length,r,l,ypos_right,ypos_left,xpos:integer;
  WaveData : TWaveData;
begin
  wave_right.Refresh;
  wave_left.Refresh;

  length:=trunc(BASS_ChannelBytes2Seconds(channel, BASS_StreamGetLength(channel)));
  BASS_ChannelGetData(Channel, @WaveData, 2048);

  pos:=0;
  for j:=1 to length do
  for i:=1 to 512 do
  begin
    BASS_ChannelSetPosition(channel,BASS_ChannelSeconds2Bytes(channel, j));
    BASS_ChannelGetData(Channel, @WaveData, 2048);
    R := SmallInt(Loword(WaveData[i]));
    L := SmallInt(HIword(WaveData[i]));
    YPos_right := Trunc((R/65535)*300)+75 ;
    YPos_left := Trunc((L/65535)*30)+75 ;
    XPos:=round(((i+pos)/(length*512)));
    pos:=pos+512;
    wave_right.Canvas.LineTo(XPos,YPos_right);
    wave_left.Canvas.LineTo(XPos,YPos_left);
  end;
end;

Das Problem ist: die Waveform wird nur korrekt (allerdings auch seeeehr langsam) Aufgebaut, wenn die Audiodatei gerade abgespielt wird. Dann ruckelt der Ton wie sau, aber die Waveform wird korrekt aufgebaut.

Wenn du mir jetzt sagst, wie man das ohne gleichzeitiges Abspielen hinbekommt, dann haben wir unsere Anzeige *g*


tschö,
Christian


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:38 Uhr.
Seite 1 von 2  1 2      

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-2025 by Thomas Breitkreuz