AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Soundkarte Frequenz wieder geben
Thema durchsuchen
Ansicht
Themen-Optionen

Soundkarte Frequenz wieder geben

Ein Thema von Desmulator · begonnen am 9. Feb 2008 · letzter Beitrag vom 10. Feb 2008
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#1

Soundkarte Frequenz wieder geben

  Alt 9. Feb 2008, 18:21
Hallo alles zusammen, ich hab in den letzten tagen sehr viel gegoogelt, allerdings wirklich nichts gefunden, und zwar suche ich eine funktion wie das windows.beep() bei der man die frequenz und die zeit angeben kann, auserdem , wenn möglich mit left und right steuerung.

was ich nicht will ist ein preperat mit sndPlaySound und einem MemoryStream.

Es kann auch ein assembler vorschlag sein, da irgendwie die winmm.dll das ja auch schaft.

naja bis denne
Lars
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: Soundkarte Frequenz wieder geben

  Alt 9. Feb 2008, 22:32
Du wirst wenn dann nicht drum herum kommen einen Buffer mit einer entsprechenden Welle zu befüllen, und diesen dann an die Soundkarte zu schieben. Ob als Stream via sndPlaySound, mit der bass.dll, oder auf einem der anderen vielen Wege einer Soundkarte etwas einzutrichtern. Aber einen Buffer irgendeiner Art brauchst du immer.

Edit: Natürlich erstmal nur wenn es um Ausgabe via Soundkarte geht. Was sich mit dem internen Piepskollegen veranstalten lässt entzieht sich meiner Kenntnis, auch ob es da irgendwo was fertiges gibt.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#3

Re: Soundkarte Frequenz wieder geben

  Alt 9. Feb 2008, 22:58
Keine Ahnung wo ich die Funktion her habe:

Delphi-Quellcode:
unit Unit2;

interface

uses
  SysUtils, Dialogs, Classes, MMSystem, Windows;

type
  TVolumeLevel = 0..127;

  procedure MakeSound(Frequency{Hz}, Duration{mSec}: Integer; Volume: TVolumeLevel);


implementation

procedure MakeSound(Frequency{Hz}, Duration{mSec}: Integer; Volume: TVolumeLevel);
  {writes tone to memory and plays it}
var
  WaveFormatEx: TWaveFormatEx;
  MS: TMemoryStream;
  i, TempInt, DataCount, RiffCount: integer;
  SoundValue: byte;
  w: double; // omega ( 2 * pi * frequency)
const
  Mono: Word = $0001;
  SampleRate: Integer = 11025; // 8000, 11025, 22050, or 44100
  RiffId: string = 'RIFF';
  WaveId: string = 'WAVE';
  FmtId: string = 'fmt ';
  DataId: string = 'data';
begin
  if Frequency > (0.6 * SampleRate) then
  begin
    ShowMessage(Format('Sample rate of %d is too Low to play a tone of %dHz',
      [SampleRate, Frequency]));
    Exit;
  end;
  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;
  MS := TMemoryStream.Create;
  with MS do
  begin
    {Calculate length of sound data and of file data} 
    DataCount := (Duration * 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'
    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
    w := 2 * Pi * Frequency; // omega
    for i := 0 to DataCount - 1 do
    begin
      SoundValue := 127 + trunc(Volume * sin(i * w / SampleRate)); // wt = w * i / SampleRate
      Write(SoundValue, SizeOf(Byte));
    end;
    {now play the sound} 
    sndPlaySound(MS.Memory, SND_MEMORY or SND_SYNC);
    MS.Free;
  end;
end;

end.
Beispiel:

Delphi-Quellcode:
uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 1000 to 2500 do
  begin
    Caption := IntToStr(i);
    MakeSound(i, 200, 60);
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#4

Re: Soundkarte Frequenz wieder geben

  Alt 9. Feb 2008, 23:01
8) die funktion ist aus der delphi fundgrube oda so und die habe ich auch schon gefunden

@Medium welche möglichkeiten gäbe es denn einer soundkarte etwas ein zu trichtern?
Lars
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#5

Re: Soundkarte Frequenz wieder geben

  Alt 9. Feb 2008, 23:13
bass.dll und dort das Beispiel \delphi\StreamTest.

Gruss
Thorsten
  Mit Zitat antworten Zitat
Flips

Registriert seit: 17. Feb 2005
Ort: Sankt Wendel
491 Beiträge
 
Delphi 7 Professional
 
#6

Re: Soundkarte Frequenz wieder geben

  Alt 10. Feb 2008, 01:21
Zitat von Popov:
Keine Ahnung wo ich die Funktion her habe
Der Vollständigkeit halber:
Swissdelphicenter
Philipp F.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#7

Re: Soundkarte Frequenz wieder geben

  Alt 10. Feb 2008, 11:04
Man könnte auch noch Bei Google suchenASIO verwenden. Aber auch dort musst du einen Buffer reinschieben.

Warum willst du nicht mit nem Stream arbeiten? Wenn du uns sagst, wo dabei das Problem liegt, können wir dir evtl. sogar noch helfen. Die o.g. Funktion ist meiner Meinung nach der sinnvollste und simpelste Weg mal eben einen Sound auszugeben. Aber solgang wir nicht wissen was an einem Stream so falsch ist, wirds schwer noch sinnvolle Alternativen zu geben - weil alle irgendwie mit einem Stream/Puffer/SpeicherDenDuFüllenMusstUndDannSchicken arbeiten.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#8

Re: Soundkarte Frequenz wieder geben

  Alt 10. Feb 2008, 13:21
Also an einem stream ist nichts falsch.

Ich bin inzwischen soweit dass ich die WinMM.dll also das MMSystem will. jedoch blicke ich bei der Documentation im msdn nicht ganz durch.

Soweit bin ich gekommen:

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, MMSystem, Classes, Windows;

var
  Wave : HWAVEOUT; { WaveOutHandle }
  WaveEx : TWaveFormatEx; { WaveEx Inhalt }
  Stream : TMemoryStream; { Stream zum abspiechern der Wellen }
  WaveHeader : TWaveHDR; { WaveHeader zum senden }

  AudioDrivers : Cardinal;
  AudioDriver : Cardinal; AudioInfo : WaveOutCaps;


{procedure SetVolume(Left, Right: Word); overload;
begin
  WriteLn('1');
end;

procedure SetVolume(Volume : Word); overload;
begin
  WriteLn('2');
  WriteLn(Volume);
end;}


begin

  { Audiotreiber ermitteln }
  AudioDrivers := waveOutGetNumDevs();
  { Alle Treiber durchlaufen }
  for AudioDriver := 0 to AudioDrivers do begin
    { Treiberinfos einholen }
    if waveOutGetDevCaps(AudioDriver, @AudioInfo, sizeof(WaveOutCaps)) = MMSYSERR_NOERROR then begin
      { Namen ausgeben }
      WriteLn(AudioInfo.szPname);
      { Infos ausdrucken }
      Write(' - MID : '); WriteLn(AudioInfo.wMid);
      Write(' - PID : '); WriteLn(AudioInfo.wPid);
      Write(' - Version : '); WriteLn(AudioInfo.vDriverVersion);
      Write(' - Formate : '); WriteLn(AudioInfo.dwFormats);
      Write(' - Channels : '); WriteLn(AudioInfo.wChannels);
      Write(' - Support : '); WriteLn(AudioInfo.dwSupport);
    end;
  end;

  { WaveEx Einstellungen }
  WaveEx.wFormatTag := WAVE_FORMAT_PCM; {PCM }
  WaveEx.nChannels := 2; { Stereo }
  WaveEx.nSamplesPerSec := 44100; { Sampelrate }
  WaveEx.wBitsPerSample := 16; { Bps }
  { Unwichtigeres }
  WaveEx.nBlockAlign := (WaveEx.nChannels * WaveEx.wBitsPerSample) div 8;
  WaveEx.nAvgBytesPerSec := WaveEx.nSamplesPerSec * WaveEx.nBlockAlign;
  WaveEx.cbSize := 0;

  { WaveForm-Audio Output Device öffnen }
  if MMSystem.waveOutOpen(@Wave,WAVE_MAPPER,@WaveEx,0,0,0) = MMSYSERR_NOERROR then
    WriteLn('WaveOut Open...')
  else
    Exit;

  { Datei einlesen }
  Stream := TMemoryStream.Create;
  Stream.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Blow3.wav');
  WriteLn(Stream.Size);

  { Datensatz erstellen }
  WaveHeader.lpData := Stream.Memory;
  WaveHeader.dwBufferLength := Stream.Size;
  WaveHeader.dwFlags := 0;


  { Header vorbereiten }
  if MMSystem.waveOutPrepareHeader(Wave,@WaveHeader,SizeOf(WaveHDR)) = MMSYSERR_NOERROR then
    WriteLn('Header prepared...')
  else
    Exit;

  { Einen Datensatz senden }
  if MMSystem.waveOutWrite(Wave,@WaveHeader,SizeOf(WaveHDR)) = MMSYSERR_NOERROR then
    WriteLn('Header writen...')
  else
    Exit;

  { Warten auf die Datensatzbeendung }
  while MMSystem.waveOutUnPrepareHeader(Wave,@WaveHeader,SizeOf(WaveHDR)) = WAVERR_STILLPLAYING do begin
    Sleep(100); //Warten
    WriteLn('Testing vor Unprepare'); //Ausgeben
  end;

  WriteLn('Header unprepared...');

  //This is the same
  //SetVolume($44,$44); SetVolume($44);

  //WriteLn($FF);

  //WriteLn($FF + $FF);

  Sleep(1000);

  { WaveForm-Audio Output Device schließen }
  MMSystem.waveOutClose(Wave);

  //PlaySound('Blow3.wav',0,0);

end.
Allerdings wir der Sound Blow3.wav nicht abgestielt, wo ist da jetzt mein denkfehler? schließlich höre ich ein rauschen
Lars
  Mit Zitat antworten Zitat
Flips

Registriert seit: 17. Feb 2005
Ort: Sankt Wendel
491 Beiträge
 
Delphi 7 Professional
 
#9

Re: Soundkarte Frequenz wieder geben

  Alt 10. Feb 2008, 14:09
Sry das ich damit so spät komme, aber das hier sollte man auch noch erwähnen.
Philipp F.
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#10

Re: Soundkarte Frequenz wieder geben

  Alt 10. Feb 2008, 16:41
Zitat von Desmulator:
8) die funktion ist aus der delphi fundgrube oda so und die habe ich auch schon gefunden
Dann sag eigentlich was du willst, denn dieses Beispiel erfüllt deine Anforderungen. Ich hab an die 4 Minuten gebraucht um das Beispiel auf der Festplatte zu suchen. Anscheinend hätte ich mir die Zeit sparen können. Also sein in Zukunft so freundlich genau zu sagen was du willst.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:07 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