Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Sound ausgabe 40 mal in der Sekunde (https://www.delphipraxis.net/46914-sound-ausgabe-40-mal-der-sekunde.html)

Six 8. Jun 2005 11:39

Re: Sound ausgabe 40 mal in der Sekunde
 
Hi FAlter,

Danke für deine Hilfe :thumb:

Könntest du mir dafür vielleicht noch mal ein kleines Codebeispiel geben (möglichst Lauffähig):

Zitat:

Setze die nicht hörbaren Bereiche auf Null (z. B. 11025 Samples lassen, 11025 Samples Null, dann wieder unverändert, ...)
Wäre es damit möglich, die 40 An- und Ausschaltvorgänge zu ralisieren und wäre es dynamisch regelbar?

Besten Dank!

Six

FAlter 8. Jun 2005 12:30

Re: Sound ausgabe 40 mal in der Sekunde
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hier erstmal ein Beispiel MIT sound.dll, eventuell solltest du die nächste Zeit mal nachsehen, ob eine neue Version herausgekommen ist. Ein Beispiel ohne DLL werde ich eventuell nach dem Zelten nachliefern. (Das reimt sich ja!)

Ansonsten versuch es einfach mal selbst oder nehm zur Wiedergabe sowas einfaches wie DelphiX (denn es ist nur die Wiedergabe, die nicht ganz reibungslos funktioniert, also PlayPCMMemory).


So, ich fahr jetzt zelten!


:hello:
:hi: CU :hi:
:hello:

Six 21. Jun 2005 17:08

Re: Sound ausgabe 40 mal in der Sekunde
 
Sorry, dass ich mich so lange nicht gemeldet hatte, aber ich hatte in letzter Zeit keinen Internet Zugang.

@ Falter: Danke für die Hilfe und deine Dateien! Ich hoffe ich komme in nächster Zeit mal dazu das ganze auszuprobieren.

Ich würde mich gerne noch weiter in das Thema einarbeiten, habe aber wie gesagt, keine kostenlosen tutorials etc. gefunden.

Hat sich denn außer Falter noch niemand mit dem Thema Soundbearbeitung und Delphi auseinandergesetzt? :gruebel:


Six

Six 21. Jun 2005 21:02

Re: Sound ausgabe 40 mal in der Sekunde
 
Soooo, also ich habe jetzt ein wenig mit deinem Beispiel (Danke, Danke Danke :mrgreen: ) herumprobiert und stellte fest, dass damit eine 40 Hz Frequenz wirklich kein Problem ist :thumb:

Den Ton an sich soll man übrigens nicht hören können, da er nur als Signal dient.
Jetzt habe ich allerdings ein Problem. Ich habe zunächst Sinus auf Square gesetzt nur höre ich jetzt bei jedem Ein- und Ausschaltvorgang ein Knacken (auch bei Sine). Es ist ganz wichtig für mich, die Steuerung komplett lautlos zu machen, wie bekomme ich also dieses Knacksen weg?

Und: Wie kann ich den linken und rechten Kanal getrennt steuern?

Zum beispiel möchte ich den rechten Kanal 10 mal in der Sekunde und den linken Kanal 20 mal in der Sekunde Ein- und Ausschalten lassen. Ist das irgendwie möglich?


Danke für eure Hilfe!

Six

FAlter 22. Jun 2005 14:08

Re: Sound ausgabe 40 mal in der Sekunde
 
Wenn TWaveFormatEx.Channels auf 2 steht, wechseln sich immer linker und rechter Channel ab, also bei 22050 Hz hast du 44100 Smallint-Werte in einer Sekunde Daten. Der erste ist links, Sample 1, der zweite ist rechts, Sample1, dann links Sample 2...

Überleg dir selbst was oder mach zwei Mono-Sounds wie zuvor dargestellt und mische sie dann zusammen (doppelt so viel Speicer wählen und dann abwechselnd Werte von einem und anderen Stream nehmen, in Zählschleife etwa

Delphi-Quellcode:
//Size = Größe der Quellsounds (beide gleich)
//ziel, quelle1, quelle2 wieder PSmallInt

GetMem(ziel, 2*size);

for i := (Size div 2) - 1 downto 0 do //div 2 wegen 16 Bit = 2 Bytes
begin
  ziel^ := quelle1^;
  inc(Ziel);
  ziel^ := quelle2^;
  inc(Ziel); // <-- edit: ergänzt, fehlte
end;
//edit: Siehe Quellcode :oops: ich glaube ich sollte mit 'nen Shortcut für den :oops: anlegen :D

Six 22. Jun 2005 17:20

Re: Sound ausgabe 40 mal in der Sekunde
 
Ok, danke, werde ich probieren.

Aber hast du auch eine Idee, wie ich das knacksen vermeiden kann? Wenn ich das nicht wegbekomme, ist die ganze Sache leider unbrauchbar :pale:

mfg Six

FAlter 22. Jun 2005 18:09

Re: Sound ausgabe 40 mal in der Sekunde
 
Naja, bei meinem Beispiel hör ich kein Kancksen...

Aber vermutlich hast du zufälligerweise eine Unterbrechung an einer Stelle der Sinuskurve, an der keine Nullstelle ist (beim Rechtecksignal gibt es keine Nullstellen, sondern einen direkten Wechsel des Vorzeichens, aber das Problem sollte das gleiche sein: Unterbrechung des Sounds an falscher Stelle).

Du könntest die Zeit der Unterbrechung unwesentlich ändern, so, dass der User es nicht merkt, aber die Zeitpunkte der Nullstellen der Funktion (bzw. bei Rechteck die Zeitpunkte des Wechsels zwischen den Vorzeichen, sind dieselben Zeitpunkte wie die Nullstellen bei Sinus) den Zeitpunkten beim ein- bzw. ausschalten des Tones entsprechen. Bei einer "normalen" Sinusfunktion kommen die Nullstellen bei allen ganzzahligen Vielfachen von Pi.

Dank unserer netten Sinusfunktion

Delphi-Quellcode:
Sin(Y * Freq * Pi * 4 / Format.nAvgBytesPerSec)
ist das hier ein wenig abgewandelt. Jede halbe Schwingungsdauer kommt eine Nullstelle, wobei eine Schwingungsdauer der Kehrwert der Frequenz ist. Bei einer Frequenz von 1 Hz ist die Schwingungsdauer 1 Sekunde, das heißt, der Nullpunkt wird alle 0,5 s durchlaufen.

Sorge also dafür, dass deine An/Aus-Vorgänge an (1 / Frequenz / 2) ausgerichtet werden. (Voraussetzung: Die An-Aus-Frequenz ist kleiner als die Tonfrequenz).

Eine andere Alternative sind Fade-in und Fade-out über nur sehr wenige Samples.

Ein Fade-in bzw. Fade-out ist das lauter- bzw. leiserwerden des Tones.

So könntest du z. B. dein gesamtes Werk lauter werden lassen:

Delphi-Quellcode:
procedure FadeInPCM16Bit(Data: PSmallInt; Size: Integer);
var
  I: Integer;
  DataLength: Integer;
begin
  DataLength := Size div 2;

  for I := 1 to DataLength do
  begin
    Data^ := Data^ * I div DataLength;
    inc(Data);
  end;
end;
Das ganze musst du so abwandeln, dass es nur einige wenige Samples entspricht, eventuell eine halbe oder eine viertel Schwingungsdauer der Tonfrequenz, und dass es an jedem Einschaltvorgang kommt.

Analog lassen sich Ausschaltvorgänge mit Fade-out realisieren... Da musst du nur die Richtung der Zählschleife umkehren... Diese dann für die Ausschaltvorgänge abwandeln...

Delphi-Quellcode:
procedure FadeInPCM16Bit(Data: PSmallInt; Size: Integer);
var
  I: Integer;
  DataLength: Integer;
begin
  DataLength := Size div 2;

  for I := DataLength - 1 downto 0 do //downto 0 ist schneller als downto 1 und der
                                      //Unterschied ist für Menschen nicht hörbar ;)
  begin
    Data^ := Data^ * I div DataLength;
    inc(Data);
  end;
end;
PS: Sources nicht getestet ;) gilt auch für vorigen Post.
//edit: uns schon die ersten Fehler gefunden :oops:
//edit2: Hab mal den Fadein-Code getestet.. hört sich scheißlich an, irgendwo kommt es da zu einem Überlauf? Data^ * I dürfte das Problem sein, delphi Rechnet das zwar intern mit 32 Bit aus und dividiert danach, aber wenn I zu groß ist... Meinetwegen rechne mit Int64-Werten, und wenn das nicht funktioniert... rechne mit Extended-Werten und verwende dann Round.

Six 22. Jun 2005 18:34

Re: Sound ausgabe 40 mal in der Sekunde
 
Danke Falter!

Ich hoffe, ich kann das auch mit dem Rechtecksignal verwenden. Da meine Frequenz bei 22000Hz liegt, sollten eigentlich genügend Nullstellen vorhanden sein. Das Rechtecksignal eignet sich für meine Zwecke deutlich besser.

Ich habe deinen Code ein wenig abgeändert, da er bei höheren Frequenzen nicht mehr funktioniert hat:

Delphi-Quellcode:
    for I := 1 to (Size div Format.nChannels) do
    begin
      if
        I mod 4450 = 0
        then
        Aus := not Aus;

      if Aus then
        Data2^ := 0;

      inc(Data2);
    end;
Das entpricht etwa 10 Ein- und Ausschaltzyklen in der Sekunde.

Würde das alles eigentlich auch mit der Bass.dll funktionieren oder wäre das ganze auch ganz ohne Dll möglich? Ich frage, weil mir durch die Dll viele Dinge verborgen bleiben, die ich eigentlich wissen müsste, um das ganze etwas besser zu verstehen... Wie hast du dir dein ganzes Wissen in diesem Bereich angeeignet?

Ich probiere dann mal die Sache mit dem Knacksen zu beseitigen. Wenn ich keinen Erfolg habe, frage ich nochmal.

Wie kann ich zwei Sounds zusammenmischen, also beispielsweise einen 500 Hz und einen 800 Hz Ton, oder zwei wav Dateien?

Abermals vielen Dank!

Six

FAlter 22. Jun 2005 18:44

Re: Sound ausgabe 40 mal in der Sekunde
 
Du kannst auch die Bass.dll verwenden, aber mit der kenn ich mich nicht so aus, aber du siehst ja, dass das ganze hauptsächlich auf Arbeit mit Pointern hinausläuft, und jede gute Audio-DLL unterstützt es, durch Angabe eines Formats, der Größe der Rohdaten und dem Pointer auf die Rohdaten den Sound wiederzugeben.

[ot]
Was mich wundert ist, dass du bei 22000 Hz = 22 kHz noch etwas hörst, ab 16 kHz können Menschen einen Ton nämlich gewöhnlcih nciht mehr wahrnehmen. Bist du ein Außerirdischer? Oder eine Mutation? Oder hast du Katzengene? (Unsere Katzen können diese Töne sicher hören, frag mal eine davon...)

Oder meintest du die Samplerate? Ich meinte im obigen Post die Frequenz des Tones selbst. Für 16 kHz benötigst du zur Speicherung mindestens 32 kHz Samplerate, aber da gehen noch sehr viele Infos verloren. Deshalb höret sich 8 kHz-Musik so schreklich an, weil alles jenseits von 4 kHz wegfällt und ein großer Teil verzerrt ist.
Wenn du mit einer niedrigen Tonfrequenz arbeitest (unter 1 kHz), dann sollten deine 22 kHz Samplerate genügen, und mit 40-Hz-Unterbrechungen sollte es auch keine Probleme mehr geben.

[/ot]

FAlter 22. Jun 2005 18:48

Re: Sound ausgabe 40 mal in der Sekunde
 
Zitat:

Zitat von Six
Wie kann ich zwei Sounds zusammenmischen, also beispielsweise einen 500 Hz und einen 800 Hz Ton, oder zwei wav Dateien?

:oops: Übersehen...

Addiere die Samples der Sounds, wenn sie sehr laut sind, dann bilde den Durchschnitt...

Delphi-Quellcode:
//Size = Größe der Quellsounds (beide gleich)
//ziel, quelle1, quelle2 wieder PSmallInt

GetMem(ziel, 2);

for i := (Size div 2) - 1 downto 0 do //div 2 wegen 16 Bit = 2 Bytes
begin
  ziel^ := (quelle1^ + quelle2^) div 2;
  inc(Ziel);
end;
Bei unterschuiedlich langen Sounds fülle den kürzeren am Ende mit Nullsamples...

//edit: Hatte versehentlich quote- statt delphi-Tags genommen :oopa: <-- der neue Standardsmiley


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:45 Uhr.
Seite 2 von 4     12 34      

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