Autor |
Beitrag |
violinenspieler1000
Beiträge: 38
|
Verfasst: Sa 14.06.08 23:14
Hallo,
ich möchte mit Delphi einen Ton erzeugen, der in Dauer und Frequenz einstellbar sein soll.
Dazu habe ich MMSystem in uses eingebunden. Ich benutze die folgende Prozedur mit Aufruf:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70:
| procedure Tform1.MakeSound(Frequency, Duration : integer);
var WaveFormatEx : TWaveFormatEx; MS : TMemoryStream; i, TempInt, DataCount, RiffCount : integer; SoundValue : byte; w : double; const Mono : Word = $0001; SampleRate : integer = 11025; 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; nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; nBlockAlign := (nChannels * wBitsPerSample) div 8; cbSize := 0; end; MS := TMemoryStream.Create; with MS do begin DataCount := (Duration * SampleRate) div 1000; RiffCount := Length(WaveId) + Length(FmtId) + SizeOf(DWord) + SizeOf(TWaveFormatEx) + Length(DataId) + SizeOf(DWord) + DataCount; Write(RiffId[1], 4); Write(RiffCount, SizeOf(DWord)); Write(WaveId[1], Length(WaveId)); Write(FmtId[1], Length(FmtId)); TempInt := SizeOf(TWaveFormatEx); Write(TempInt, SizeOf(DWord)); Write(WaveFormatEx, SizeOf(TWaveFormatEx)); Write(DataId[1], Length(DataId)); Write(DataCount, SizeOf(DWord)); w := 2 * Pi * Frequency; for i := 0 to DataCount - 1 do begin SoundValue := 127 + trunc(127 * sin(i * w / SampleRate)); Write(SoundValue, SizeOf(Byte)); end; sndPlaySound(MS.Memory, SND_MEMORY or SND_SYNC); MS.Free; end; end;
procedure TForm1.Button1Click(Sender: TObject); begin MakeSound(100,60000); end; |
Leider funktioniert das nicht. Weiß jemand, wo der Fehler ist?
Maik
Moderiert von AXMD: Delphi-Tags hinzugefügt
|
|
Marc.
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Sa 14.06.08 23:17
Hi und im Forum!
Was funktioniert nicht? Was spricht gegen die Verwendung von Windows.Beep(Frequ, Laenge); ?
€: Code-Tags -> [code] [/code ] oder analog dazu Delphi-Tags -> [delphi] [/delphi ]
Grüße,
Marc
|
|
violinenspieler1000
Beiträge: 38
|
Verfasst: Sa 14.06.08 23:48
Mit meiner Prozedur kommt einfach kein Ton.
Mit Windows.Beep(Frequ, Laenge); wird doch kein Ton über die Lautsprecher ausgegeben, oder?
Maik
|
|
Marc.
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Sa 14.06.08 23:50
Bei mir schon. Du hättest es aber auch selbst ausprobieren können.
|
|
violinenspieler1000
Beiträge: 38
|
Verfasst: Sa 14.06.08 23:58
Bei mir wird Windows.Beep(Frequ, Laenge); auf einem lautsprecher im computer ausgegeben (muss dasselbe ding sein, dass beim hochfahren einmal piep macht).
Kann man das irgendwie umstellen?
Maik
|
|
Marc.
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: So 15.06.08 18:57
Ich habe Deine Procedure MakeSound nun getestet. Resultat: Funktioniert einwandfrei.
Ich tippe mal stark darauf, dass deine Boxen nicht korrekt angeschlossen oder eingerichtet sind.
Grüße,
Marc
|
|
hui1991
Beiträge: 433
Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
|
Verfasst: So 15.06.08 19:58
Also ich hab das getestet mit Turbo Delphi Explorer auf Vista und es funktioniert nicht. Ich drück auf den Button und es passiert garnichts.
|
|
matox
Hält's aus hier
Beiträge: 4
Erhaltene Danke: 1
XP
Delphi 7.0 Personal
|
Verfasst: Do 26.06.08 14:02
habe das heute mit XP getestet und nachdem ich den Procedure-Namen auf MakeSound gekürzt
habe gibt die Procedure alle Töne über die Lautsprecher aus.
procedure MakeSound(Frequency, Duration : integer);
Nachstehend die Tonleiter C2 - C3.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.Button1Click(Sender: TObject); begin MakeSound(523,600); MakeSound(587,600); MakeSound(659,600); MakeSound(698,600); MakeSound(784,600); MakeSound(880,600); MakeSound(987,600); MakeSound(1046,600); end; |
Gruß matox
Moderiert von AXMD: Delphi-Tags hinzugefügt
Für diesen Beitrag haben gedankt: Jakane
|
|
Gelmo
Hält's aus hier
Beiträge: 5
Erhaltene Danke: 1
Win XP
Delphi 2005 prof.
|
Verfasst: Mo 22.04.13 11:22
Hallo zusammen!
Auf der Suche nach einer EINFACHEN Möglichkeit, mit Delphi einen Ton aus Frequenz- und Dauer-Angabe zu generieren, bin ich wiederholt auf diesen Beitrag gestoßen. Daher antworte ich jetzt darauf nach fast fünf Jahren. Ich habe den Code in eine eigene Unit kopiert und aus meinem Programm testweise aufgerufen. Ich erhalte aber keinen Ton.
Es passiert auch nichts, wenn ich die Zeilen 24 und 25 des Listings vertausche, was vermutlich nötig ist, da Zeile 24 auf die in Zeile 25 definierte Variable zugreift.
Kurz gefragt: Gibt es inzwischen in Delphi immer noch keine Möglichkeit, einfach einen Ton zu generieren. Ich verwende - als Hobby-Programmierer - zur Zeit Delphi XE Starter und werde mir auch keine teure Profi-Version mehr zulegen.
Freundliche Grüße von Gelmo
Für diesen Beitrag haben gedankt: Frolo
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 22.04.13 14:44
Im folgenden Code wird das Device Beep erzeugt bzw. genutzt -
es funktioniert auch unter WIN 7 - 64Bit
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject);
private public end;
var Form1: TForm1;
type BEEP_SET_PARAMETERS= record Frequency,Duration:cardinal; end;
const IOCTL_BEEP_SET=$10000; FNStr:array [0..9] of char='\\.\huii'#0; FN:PChar=@FNStr[0]; DEVNAME : PChar=@FNStr[3];
var DEVPATH:array [0..MAX_PATH] of char;
implementation
{$R *.dfm}
function WindowsBeep(Freq,Duration:cardinal):longint; var hBeep, bRET : cardinal; BSP : BEEP_SET_PARAMETERS; ODN : longbool; begin ODN:=false; if QueryDosDevice(DEVNAME,DEVPATH,MAX_PATH)=0 then begin DefineDosDevice(DDD_RAW_TARGET_PATH,DEVNAME,'\Device\Beep'); ODN:=true; end; hBeep:=CreateFile (FN,GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0); if hBeep=INVALID_HANDLE_VALUE then begin Result:=E_FAIL; exit; end; BSP.Frequency:= Freq; BSP.Duration:= Duration; DeviceIOControl(hBeep,IOCTL_BEEP_SET,@Freq,sizeof(BSP),nil,0,bRET,nil); if ODN then DefineDosDevice(DDD_REMOVE_DEFINITION,DEVNAME,nil); Sleep(BSP.Duration); CloseHandle(hBeep); Result:=S_OK; end; Procedure DLAY; BEGIN sleep(0); END;
procedure TForm1.FormCreate(Sender: TObject); begin WindowsBeep(3000,150); end;
procedure TForm1.Button1Click(Sender: TObject); begin WindowsBeep(1000,150); end;
procedure TForm1.Button2Click(Sender: TObject); var i:Integer; begin for I := 1 to 10 do BEGIN WindowsBeep(I*500,100); DLAY; END; end; |
|
|
bummi
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Mo 22.04.13 14:54
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
Gelmo
Hält's aus hier
Beiträge: 5
Erhaltene Danke: 1
Win XP
Delphi 2005 prof.
|
Verfasst: Di 23.04.13 11:50
Hallo!
Habe das Listing in ein Testprogramm mit zwei Formularen eingebaut. Im 1. werden Frequenz und Dauer bestimmt, im 2. befindet sich das Listing oben, natürlich angepasst auf Form2. Übergebe dann an WindowsBeep die Parameter. Dabei wird kein Ton ausgegeben. Ich vermute, dass die Werte für die im Code verwendeten Variablen durch Windows ermittelt werden. Oder müsste ich eine oder mehrere davon neben Freuquenz und Dauer selbst übergeben?
Übrigens Windows.beep(...) funktioniert, aber wer will schon "Beep"-Musik hören?
Dennoch vielen Dank, Gelmo
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 23.04.13 18:09
Wenn Du guten Sound haben willst, musst Du MIDI nehmen.
Da kann man unter 127 Instrumenten auswählen, die Lautstärke einstellen für L+R u.a.
In WINDOWS ist als Device Microsoft GS Wavetable Synth vorhanden.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, MMSystem, ComCtrls;
type TMIDIInstrument = (midiAcousticGrandPiano, midiBrightAcousticPiano, midiElectricGrandPiano, midiHonkyTonkPiano, midiRhodesPiano, midiChorusedPiano, midiHarpsichord, midiClavinet, midiCelesta, midiGlockenspiel, midiMusicBox, midiVibraphone, midiMarimba, midiXylophone, midiTubularBells, midiDulcimer, midiHammondOrgan, midiPercussiveOrgan, midiRockOrgan, midiChurchOrgan, midiReedOrgan, midiAccordion, midiHarmonica, midiTangoAccordion, midiAcousticGuitarNylon, midiAcousticGuitarSteel, midiElectricGuitarJazz, midiElectricGuitarClean, midiElectricGuitarMuted, midiOverdrivenGuitar, midiDistortionGuitar, midiGuitarHarmonics, midiAcousticBass, midiElectricBassFinger, midiElectricBassPick, midiFretlessBass, midiSlapBass1, midiSlapBass2, midiSynthBass1, midiSynthBass2, midiViolin, midiViola, midiCello, midiContrabass, midiTremoloStrings, midiPizzicatoStrings, midiOrchestralHarp, midiTimpani, midiStringEnsemble1, midiStringEnsemble2, midiSynthStrings1, midiSynthStrings2, midiChoirAahs, midiVoiceOohs, midiSynthVoice, midiOrchestraHit, midiTrumpet, midiTrombone, midiTuba, midiMutedTrumpet, midiFrenchHorn, midiBrassSection, midiSynthBrass1, midiSynthBrass2, midiSopranoSax, midiAltoSax, midiTenorSax, midiBaritoneSax, midiOboe, midiEnglishHorn, midiBassoon, midiClarinet, midiPiccolo, midiFlute, midiRecorder, midiPanFlute, midiBottleBlow, midiShakuhachi, midiWhistle, midiOcarina, midiLead1Square, midiLead2Sawtooth, midiLead3CalliopeLead, midiLead4ChiffLead, midiLead5Charang, midiLead6Voice, midiLead7Fifths, midiLead8BrassLead, midiPad1NewAge, midiPad2Warm, midiPad3Polysynth, midiPad4Choir, midiPad5Bowed, midiPad6Metallic, midiPad7Halo, midiPad8Sweep, midiEmpty0, midiEmpty1, midiEmpty2, midiEmpty3, midiEmpty4, midiEmpty5, midiEmpty6, midiEmpty7, midiEmpty8, midiEmpty9, midiEmpty10, midiEmpty11, midiEmpty12, midiEmpty13, midiEmpty14, midiEmpty15, midiEmpty16, midiEmpty17, midiEmpty18, midiEmpty19, midiEmpty20, midiEmpty21, midiEmpty22, midiEmpty23, midiGuitarFretNoise, midiBreathNoise, midiSeashore, midiBirdTweet, midiTelephoneRing, midiHelicopter, midiApplause, midiGunshot);
type TForm1 = class(TForm) Button10: TButton; Button33: TButton; Button41: TButton; Button42: TButton; Button43: TButton; Button44: TButton; TrackBar1: TTrackBar; ComboBox1: TComboBox; procedure Button10Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button33Click(Sender: TObject); procedure Button41Click(Sender: TObject); procedure Button42Click(Sender: TObject); procedure Button43Click(Sender: TObject);
private public procedure GetMidiVolume(var volLe, volRi: Word); procedure SetMidiVolume(var volLe, volRi: Word); end;
var Form1: TForm1; mo: HMIDIOUT; volLe, volRi: Word;
const MIDI_NOTE_ON = $90; MIDI_NOTE_OFF = $80; MIDI_CHANGE_INSTRUMENT = $C0;
MAX_VOLUME = 65535; HALF_VOLUME = 32768; MIN_VOLUME = 0; FADE_SPEED = 64;
implementation
{$R *.dfm} function MIDIEncodeMessage(Msg, Param1, Param2: byte): integer; begin result := Msg + (Param1 shl 8) + (Param2 shl 16); end;
procedure NoteOn(NewNote, NewIntensity: byte); begin midiOutShortMsg(mo, MIDIEncodeMessage(MIDI_NOTE_ON, NewNote, NewIntensity)); end;
procedure NoteOff(NewNote, NewIntensity: byte); begin midiOutShortMsg(mo, MIDIEncodeMessage(MIDI_NOTE_OFF, NewNote, NewIntensity)); end;
procedure SetInstrument(NewInstrument: byte); begin midiOutShortMsg(mo, MIDIEncodeMessage(MIDI_CHANGE_INSTRUMENT, NewInstrument, 0)); end;
procedure SetCurrentInstrument2(NewInstrument: Integer); begin midiOutShortMsg(mo, MIDIEncodeMessage(MIDI_CHANGE_INSTRUMENT, NewInstrument, 0)); end;
procedure SetCurrentInstrument(CurrentInstrument: TMIDIInstrument); begin midiOutShortMsg(mo, MIDIEncodeMessage(MIDI_CHANGE_INSTRUMENT, ord(CurrentInstrument), 0)); end;
procedure InitMIDI; begin midiOutOpen(@mo, 0, 0, 0, CALLBACK_NULL); midiOutShortMsg(mo, MIDIEncodeMessage(MIDI_CHANGE_INSTRUMENT, 0, 0)); end;
procedure SetPlaybackVolume(PlaybackVolume: cardinal); begin midiOutSetVolume(mo, PlaybackVolume); Form1.TrackBar1.Position:= PlaybackVolume; Form1.Trackbar1.SelEnd:= Form1.TrackBar1.Position; end;
procedure TForm1.GetMidiVolume(var volLe, volRi: Word); var vol: DWORD; begin volLe := 0; volRi := 0; midiOutGetVolume(0, @vol); volLe := vol and $FFFF; volRi := vol shr 16; end;
procedure TForm1.SetMidiVolume(var volLe, volRi: Word); var vol: DWORD; begin vol := volLe + volRi shl 16; midiOutSetVolume(0, vol); end; procedure TForm1.Button10Click(Sender: TObject); begin NoteOn(50, 127); Sleep(500); NoteOff(50, 127); SetInstrument(60); NoteOn(60, 127); Sleep(500); NoteOff(60, 127); SetInstrument(80); NoteOn(70, 127); Sleep(500); NoteOff(70, 127); SetInstrument(90); NoteOn(80, 127); Sleep(500); NoteOff(80, 127); SetInstrument(100); NoteOn(90, 127); Sleep(500); NoteOff(90, 127); SetInstrument(12); NoteOn(40, 127); Sleep(1000); NoteOff(40, 127); end;
procedure TForm1.Button33Click(Sender: TObject); begin SetCurrentInstrument(midiHarmonica); SetPlaybackVolume(65535); NoteOn(50, 127); sleep(200); NoteOn(60, 127); sleep(200); NoteOn(70, 127); sleep(200); NoteOff(70, 127); NoteOff(60, 127); NoteOff(50, 127); SetCurrentInstrument(midiAcousticGrandPiano); SetPlaybackVolume(32000); NoteOn(70, 127); NoteOn(80, 127); sleep(1000); NoteOff(80, 127); NoteOff(70, 127); SetCurrentInstrument(midiApplause); SetPlaybackVolume(65535); NoteOn(64, 127); sleep(2000); NoteOff(64, 127); end;
procedure TForm1.Button41Click(Sender: TObject); begin SetPlaybackVolume(MAX_VOLUME); end;
procedure TForm1.Button42Click(Sender: TObject); begin SetPlaybackVolume(HALF_VOLUME); end;
procedure TForm1.Button43Click(Sender: TObject); begin SetPlaybackVolume(0); end;
procedure GetMidiOutDevices2; var dev: Integer; caps: TMidiOutCaps; begin Form1.ComboBox1.Clear; for dev := 0 to midiOutGetNumDevs - 1 do begin midiOutGetDevCaps(dev, @caps, sizeof(TMidiOutCaps)); Form1.ComboBox1.Items.Add(caps.szPname); end; Form1.ComboBox1.ItemIndex := 0; end;
procedure TForm1.FormCreate(Sender: TObject); begin GetMidiOutDevices2; InitMIDI; end;
end. |
Einloggen, um Attachments anzusehen!
Zuletzt bearbeitet von hathor am Di 23.04.13 19:02, insgesamt 2-mal bearbeitet
|
|
FinnO
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: Di 23.04.13 18:19
hathor hat folgendes geschrieben : | Wenn Du guten Sound haben willst, musst Du MIDI nehmen.
Da kann man unter 127 Instrumenten auswählen, die Lautstärke einstellen für L+R u.a. |
Moin,
also irgendwo hört der Spaß dann auch mal auf. MIDI ist in erster Linie ein Protokoll für elektronische Eingabegeräte, z.B. Keyboards. Wenn er guten Sound haben will, muss er sich in Softwaresynthese von Sounds einarbeiten. Und wenn er den Sound dann auch noch selbst ausgeben will, dann auch in Soundausgabe, Bufferhandling etc. Das kann man mit WMI machen, ist aber wirklich nicht leicht. Martok kann das . Die Sache geht bestimmt auch mit der bass.dll oder sowas. Aber davon habe ich wirklich keine Ahnung.
Gruß
|
|
Gelmo
Hält's aus hier
Beiträge: 5
Erhaltene Danke: 1
Win XP
Delphi 2005 prof.
|
Verfasst: Fr 03.05.13 15:12
Hallo zusammen!
War einige Tage im Urlaub und kann mich erst jetzt wieder hier melden. Den Beitrag von Hathor finde ich durchaus nicht lächerlich. Bisher habe ich mit dem Code noch keinen Ton erzeugt. Habe diesen in ein Testprogramm eingefügt mit den entsprechenden Komponenten. Beim Kompilieren wird kein Fehler mehr angezeigt, aber es kommt auch kein Ton. Vielleicht klappt es ja, wenn ich noch etwas experimentiere.
Mit Softwaresynthese oder Soundausgabe möchte ich mich bei meinen Vorkenntnissen nicht befassen. Dann stellt Delphi eben auf akustischem Gebiet im Gegensatz zu den graphischen Komponenten keine Objekte zur Verfügung.
Nochmals vielen Dank, mit freundlichen Grüßen
Gelmo
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 03.05.13 17:25
Welches BS?
Vielleicht ist die Software für den Soundchip nicht vollständig installiert.
Name des Soundchips?
Wird beim Test-Programm in der Combobox nach dem Start gleich etwas angezeigt (Microsoft GS Wavetable Synth)?
|
|
Mathematiker
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Fr 03.05.13 23:24
Hallo hathor,
hathor hat folgendes geschrieben : | Wenn Du guten Sound haben willst, musst Du MIDI nehmen. |
Ich habe Dein Beispiel ausprobiert und finde es ziemlich gut.
Meine eigenen Versuche, vernünftige Töne zu erzeugen, gingen aber voll in die Hose.
Irgendwie bin ich noch nicht dahinter gekommen, was bei
Delphi-Quelltext 1: 2: 3: 4:
| procedure NoteOn(NewNote, NewIntensity: byte); begin midiOutShortMsg(mo, MIDIEncodeMessage(MIDI_NOTE_ON, NewNote, NewIntensity)); end; |
der Parameter NewNote beschreibt. Die Frequenz kann es nicht sein, aber welcher Wert ist das dann?
Sind die Töne durchnumeriert? Aber wie?
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
FinnO
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: Fr 03.05.13 23:26
Ohne Kenntnis behaupte ich, dass die Töne gemäß dem MIDI-Standard von 0-127 durchnummeriert sind.#
Du kannst natürlich auch umrechnen:
Quelltext 1:
| fm = 2^((m−69)/12) * (440 Hz) |
Mit der Annahme, dass 440Hz der Kammerton ist.
Für diesen Beitrag haben gedankt: Mathematiker
|
|
Mathematiker
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Fr 03.05.13 23:32
Hallo,
FinnO hat folgendes geschrieben : | Du kannst natürlich auch umrechnen:
Quelltext 1:
| fm = 2^((m−69)/12) * (440 Hz) | |
Danke. Das ist genau das, was ich suche.
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Martok
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Sa 04.05.13 00:11
Moin!
Und wie immer gibt es ein DGL-Tutorial dazu: Software-Synthesizer.
Nun ist das durchaus nicht der Weisheit letzter Schluss, das was FinnO weiter oben meint hat mich auch ein paar Wochen Forschungsarbeit gekostet (und das war nicht genug um's komplett zum Funktionieren zu kriegen, gibt ein paar Threads dazu hier). Und es wird nicht unbedingt dadurch einfacher dass Microsoft in jeder Windowsversion ein neues Soundsystem einführt. Deswegen dürfte vermutlich auch die MMSystem-Version nicht mehr funktionieren, auch wenn der Code an sich (auf den ersten Blick, der kommt mir "von früher" bekannt vor) nicht kaputt ist.
Im Endeffekt gehts aber immer nur um eins: irgendwo schreibst du das Signal hin und lässt es auf die Soundkarte schieben.
"Jemand" sollte mal eine Bibliothek für sowas schreiben. Problem: je nach Anforderung kann man durchaus komplett andere Ansätze wählen. Fmod mag ich nicht so (vor allem wegen der aktuellen undurchsichtigen Lizenz), Bass geht wunderbar aber schwierig mit Threads, die MMSystem-waveOut-API gibt's immer noch (wenn sie mal funktioniert) und direkt per OpenAL o.ä. könnte man auch noch ran.
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
|