Autor Beitrag
violinenspieler1000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: 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:


ausblenden volle Höhe Delphi-Quelltext
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);
{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
  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
    {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
      // wt = w *i /SampleRate
      SoundValue := 127 + trunc(127 * sin(i * w / SampleRate));
      Write(SoundValue, SizeOf(Byte));
    end;
    // you could save the wave tone to file with :
    // MS.Seek(0, soFromBeginning);
    // MS.SaveToFile('C:\MyFile.wav');
    // then reload and play them without having to
    // construct them each time.
    {now play the sound}
    sndPlaySound(MS.Memory, SND_MEMORY or SND_SYNC);
    MS.Free;
  end;
end{Alan Lloyd}



procedure TForm1.Button1Click(Sender: TObject);
begin
MakeSound(100,60000);
end;



Leider funktioniert das nicht. Weiß jemand, wo der Fehler ist?

Maik

Moderiert von user profile iconAXMD: Delphi-Tags hinzugefügt
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Sa 14.06.08 23:17 
Hi und :welcome: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Sa 14.06.08 23:50 
Bei mir schon. Du hättest es aber auch selbst ausprobieren können. ;)
violinenspieler1000 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: 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
BeitragVerfasst: 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.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.Button1Click(Sender: TObject);
     begin
  MakeSound(523,600); //C 2
  MakeSound(587,600); //D
  MakeSound(659,600); //E
  MakeSound(698,600); //F
  MakeSound(784,600); //G
  MakeSound(880,600); //H
  MakeSound(987,600); //A
  MakeSound(1046,600);//C 3
    end;


Gruß matox

Moderiert von user profile iconAXMD: 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.
BeitragVerfasst: 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



BeitragVerfasst: Mo 22.04.13 14:44 
Im folgenden Code wird das Device Beep erzeugt bzw. genutzt -
es funktioniert auch unter WIN 7 - 64Bit


ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

type  BEEP_SET_PARAMETERS= record
      Frequency,Duration:cardinal;
      end;

const IOCTL_BEEP_SET=$10000;
      FNStr:array [0..9of 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Mo 22.04.13 14:54 
vielleicht ist das ja was für Dich
stackoverflow.com/qu...ound-notes-in-delphi

_________________
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.
BeitragVerfasst: 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



BeitragVerfasst: 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.

ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    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}
//-----------------------------------------------------------------MIDI
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, 000, CALLBACK_NULL);
  midiOutShortMsg(mo, MIDIEncodeMessage(MIDI_CHANGE_INSTRUMENT, 00));
end;

procedure SetPlaybackVolume(PlaybackVolume: cardinal); // 0 - 65535
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;
 //Weiterbearbeitung...
end;

procedure TForm1.SetMidiVolume(var volLe, volRi: Word);
var vol: DWORD;
begin
 vol := volLe + volRi shl 16;
 midiOutSetVolume(0, vol);
end;
//-----------------------------------------------------------------MIDI - Ende
procedure TForm1.Button10Click(Sender: TObject);
begin
NoteOn(50127);
Sleep(500);
NoteOff(50127);
SetInstrument(60);
NoteOn(60127);
Sleep(500);
NoteOff(60127);
SetInstrument(80);
NoteOn(70127);
Sleep(500);
NoteOff(70127);
SetInstrument(90);
NoteOn(80127);
Sleep(500);
NoteOff(80127);
SetInstrument(100);
NoteOn(90127);
Sleep(500);
NoteOff(90127);
SetInstrument(12);
NoteOn(40127);
Sleep(1000);
NoteOff(40127);
end;

procedure TForm1.Button33Click(Sender: TObject);
begin
  SetCurrentInstrument(midiHarmonica);
  SetPlaybackVolume(65535);
  NoteOn(50127);
  sleep(200);
  NoteOn(60127);
  sleep(200);
  NoteOn(70127);
  sleep(200);
  NoteOff(70127);
  NoteOff(60127);
  NoteOff(50127);
  SetCurrentInstrument(midiAcousticGrandPiano);
  SetPlaybackVolume(32000);
  NoteOn(70127);
  NoteOn(80127);
  sleep(1000);
  NoteOff(80127);
  NoteOff(70127);
  SetCurrentInstrument(midiApplause);
  SetPlaybackVolume(65535);
  NoteOn(64127);
  sleep(2000);
  NoteOff(64127);
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//primäre Soundkarte
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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Di 23.04.13 18:19 
user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:
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. user profile iconMartok 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.
BeitragVerfasst: 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



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Fr 03.05.13 23:24 
Hallo hathor,
user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:
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
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Fr 03.05.13 23:32 
Hallo,
user profile iconFinnO hat folgendes geschrieben Zum zitierten Posting springen:
Du kannst natürlich auch umrechnen:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: 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 user profile iconFinnO 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."