![]() |
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:
Besten Dank! Six |
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: |
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 |
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 |
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:
//edit: Siehe Quellcode :oops: ich glaube ich sollte mit 'nen Shortcut für den :oops: anlegen :D
//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; |
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 |
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:
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.
Sin(Y * Freq * Pi * 4 / Format.nAvgBytesPerSec)
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:
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.
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; 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:
PS: Sources nicht getestet ;) gilt auch für vorigen Post.
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; //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. |
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:
Das entpricht etwa 10 Ein- und Ausschaltzyklen in der Sekunde.
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; 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 |
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] |
Re: Sound ausgabe 40 mal in der Sekunde
Zitat:
Addiere die Samples der Sounds, wenn sie sehr laut sind, dann bilde den Durchschnitt...
Delphi-Quellcode:
Bei unterschuiedlich langen Sounds fülle den kürzeren am Ende mit Nullsamples...
//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; //edit: Hatte versehentlich quote- statt delphi-Tags genommen :oopa: <-- der neue Standardsmiley |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:45 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-2025 by Thomas Breitkreuz