AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Delphi Sound aufnehmen
Tutorial durchsuchen
Ansicht
Themen-Optionen

Sound aufnehmen

Ein Tutorial von overmoon · begonnen am 21. Aug 2003 · letzter Beitrag vom 17. Jan 2016
Antwort Antwort
Seite 6 von 10   « Erste     456 78     Letzte »    
Benutzerbild von overmoon
overmoon
Registriert seit: 8. Aug 2003
Sound aufnehmen

Auf den Vorschlag von Matze habe ich aus zwei meiner Beiträge ein Tutorial zusammengebastelt. Vielleicht kann es irgendjemand irgendwann irgendwozu brauchen.

Also Dinge aufnehmen geht mit Delphi und der Unit mmSystem richtig einfach.

Der Schlüssel ist die Prozedur "mciSendString". Über diese Prozedur kann man die Komplette Aufnahme des Wave-Files machen.

1.) Wir müssen ein Audiogerät öffnen. Ich nenne es einfach mal "mySound".

mciSendString('OPEN NEW TYPE WAVEAUDIO ALIAS mySound',nil,0,Handle);
2.) Nun müssen wir die Optionen für die Audioaufnahme einstellen. Da für gibt es einige Einstellungen:

- BitsPerSample (Wie genau wird ein analoger Wert abgetastet; meist 8 oder 16)

- Channels (Mono(1) oder Stereo (2))

- SamplesPerSec (Abtastungen pro Sekunde; 800,11025,22050,44100)

Damit wäre eigentlich alles angegeben, was man braucht. Damit es funktioniert, müssen noch zwei weitere Dinge angegeben werden. Lässt man diese weg, gibt es Probleme.

- BytesPerSec (= (BitsPerSample div 8)*Channels*SamplesPerSec )

- Alignment (= Channels*(BitsPerSample div 8) )

Die Prozedur zum Einstellen der Einstellungen sieht dann folgendermaßen aus:

Delphi-Quellcode:
mciSendString('SET mySound ' +
                   'TIME FORMAT MS ' +
                   'BITSPERSAMPLE 16 ' +
                   'CHANNELS 2 ' +
                   'SAMPLESPERSEC 44100 ' +
                   'BYTESPERSEC 176400 ' +
                   'ALIGNMENT 4',
                   nil,0,handle);
3.) Das Starten der Aufnahme:

Das folgende erklärt sich eigentlich von selbst:

mciSendString('RECORD mySound',nil,0,Handle);
4.) Genauso einfach ist das Stoppen der Aufnahme:

mciSendString('STOP mySound',nil,0,Handle);
5.) Nach erfolgter Aufnahme wollen wir die Datei natürlich nicht im Nirvana des OS verschwinden lassen... wir müssen sie speichern.

Das geht folgendermaßen:

mciSendString('SAVE mySound "c:\datei.wav"',nil,0,Handle);

6.) Schließlich muss man noch das Audiogerät "mySound", welches man am Anfang geöffnet hatte, schließen.

mciSendString('CLOSE mySound',nil,0,Handle);
Und wir sind fertig mit der Aufnahme.

7.) Weitere Aufgaben, die man über "mciSendString" machen kann sind z.B. noch: PLAY, WAIT und LOAD


8.) Die Aufnahmen werden nur leider recht groß, deshalb macht sich eine Konvertierung zu Mp3 recht gut.

Dazu bietet sich der lame - Encoder an.

Den bekommst du hier:
http://lame.sourceforge.net/

Dort bekommst du die lame_enc.dll und die lame.exe .
Kannst du eigentlich nehmen, was du willst, konvertieren beide brav waves nach Mp3.

Die lame.exe musst du z.B. einfach mit entsprechenden Parametern aufrufen.


Zur Lizenz vom Lame_Ecoder:

Zitat:
Can I use LAME in my commercial program?

Yes, you can, under the restrictions of the LGPL. The easiest
way to do this is to:

1. Link to LAME as separate library (libmp3lame.a on unix or
lame_enc.dll on windows)

2. Fully acknowledge that you are using LAME, and give a link
to our web site, www.mp3dev.org

3. If you make modifications to LAME, you *must* release these
these modifications back to the LAME project, under the LGPL.

overmoon
"Habe Mut, dich deines eigenen Verstandes zu bedienen." (Immanuel Kant)
 
Tropby
 
#51
  Alt 6. Dez 2006, 20:21
Kann es sein das ich den @fWaveData[pwh.dwUser].header erstmal leeren muss ??
  Mit Zitat antworten Zitat
Benutzerbild von Sunlight7
Sunlight7

 
Delphi 5 Standard
 
#52
  Alt 6. Dez 2006, 20:34
Was willst Du da ausleeren?

Evtl. ein Un/PrepareHeader.
Ich mach das nicht, aber wie gesagt, ich mach es mit der CallBack.

Aber eher denke ich an einen Pointer Fehler.
  Mit Zitat antworten Zitat
Tropby
 
#53
  Alt 6. Dez 2006, 21:04
Hm gut dass ich mich damit nicht so gut auskenne XD

Edit : Wenn ich langsam durch gehe kommt kein Fehler aber wenn ich das Programm einfach laufen lasse dann kommt der Fehler

Edit 2 :

Der Fehler leigt bei :
   pwh:=PWaveHdr(dwParam1)^;
  Mit Zitat antworten Zitat
Benutzerbild von Sunlight7
Sunlight7

 
Delphi 5 Standard
 
#54
  Alt 6. Dez 2006, 21:40
Sag ich doch, Pointer Fehler, scheint bei der Nachrichtenmethode etwas anders zu funktionieren.

Definiere "Fehler"
  Mit Zitat antworten Zitat
Tropby
 
#55
  Alt 6. Dez 2006, 21:49
Also wenn ich das Projekt starte kommt da so nen Fehler (siehe Bilder)

Und dann geht halt nichts mehr. Könnte aber auch an diesem Code liegen :

Delphi-Quellcode:
procedure waveInProc(hwi: HWAVEIN; uMsg: UINT; dwInstance, dwParam1, dwParam2 : DWord); stdcall;
var
  classinstance: TWaveIn absolute dwInstance;
  pwh:TWaveHdr;
begin
 if umsg = WIM_DATA then
 begin
   pwh:=PWaveHdr(dwParam1)^;
   with classinstance do
   begin
     fWaveData[pwh.dwUser].Stream.Write(fWaveData[pwh.dwUser].Data, fWaveData[pwh.dwUser].header.dwBytesRecorded);

     if fWaveData[pwh.dwUser].Header.dwFlags and MHDR_DONE = MHDR_DONE then
     begin
       fWaveData[pwh.dwUser].Stream.Position := 0;
       if Assigned(fOnData) then
         fOnData(fWaveData[pwh.dwUser].Stream);
       fWaveData[pwh.dwUser].Stream.Clear;
     end;

// fWaveData[pwh.dwUser].Header.lpData := fWaveData[pwh.dwUser].Data;
     fWaveData[pwh.dwUser].Header.dwBufferLength := cWaveBufferSize;
     fWaveData[pwh.dwUser].Header.dwFlags := 0;
     fWaveData[pwh.dwUser].Header.dwBytesRecorded := 0;


     waveInPrepareHeader(fHandle, @fWaveData[pwh.dwUser].Header, SizeOf(fWaveData[pwh.dwUser].data));
     waveInAddBuffer(fHandle, @fWaveData[pwh.dwUser].Header, SizeOf(fWaveData[pwh.dwUser].data));
   end;
 end;
end;
Angehängte Grafiken
Dateityp: jpg fehler_530.jpg (391,8 KB, 29x aufgerufen)
Dateityp: jpg fehler2_181.jpg (1,18 MB, 36x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Sunlight7
Sunlight7

 
Delphi 5 Standard
 
#56
  Alt 6. Dez 2006, 22:15
1.8 MB Screenshot
Mit meinem Modem lad' ich mir das net runter

waveInPrepareHeader(fHandle, @fWaveData[pwh.dwUser].Header, SizeOf(fWaveData[pwh.dwUser].data)); Ist IMHO nach unnötig.

Hmm, hab jetzt den Code kompiliert, läuft ohne Fehler
Mal abgesehen von den Compilermeldungen, etwas sehr nachlässig programmiert...

Edit: Was machste eigentlich in der OnData?
Genaugenommen darfste da nicht auf die VCL Zugreifen und (fast) keine API Funktionen aufrufen.
  Mit Zitat antworten Zitat
Tropby
 
#57
  Alt 7. Dez 2006, 11:29
Oh hab vergessen die Screenshots zu komprimieren


Das ist mein OnData :


Delphi-Quellcode:
procedure TForm1.OnData(const aStream: TMemoryStream);
var header: TWaveHdr;
begin
  header.lpData := aStream.Memory;
  header.dwBufferLength := cWaveBufferSize;
  header.dwFlags := 0;
  waveOutPrepareHeader(fhandle, @header, cWaveBufferSize);
  waveOutWrite(fhandle, @header, cWaveBufferSize);
end;
Zitat:
Hmm, hab jetzt den Code kompiliert, läuft ohne Fehler Grübelnd...
Mal abgesehen von den Compilermeldungen, etwas sehr nachlässig programmiert...
Ähm ja ich bin ja noch nicht wirklich drin was das alles mit den pointern und so angeht ^^
und das ist eher bei mir im Moment ein ausprobieren als ein wissen.
  Mit Zitat antworten Zitat
Benutzerbild von Sunlight7
Sunlight7

 
Delphi 5 Standard
 
#58
  Alt 7. Dez 2006, 14:57
Zitat von Tropby:
Oh hab vergessen die Screenshots zu komprimieren
Dann mach es jetzt noch

Zitat von Tropby:
Ähm ja ich bin ja noch nicht wirklich drin was das alles mit den pointern und so angeht ^^
und das ist eher bei mir im Moment ein ausprobieren als ein wissen.
Der Original Source ist nachlässig programmiert, das war nicht gegen Dich, ich weiß, das Du n Neuling bist
Schau Dich mal bei Hier im Forum suchenResult um, Rückgabewerte sollten überprüft werden, sonst hat es gar keinen Sinn diese zu speichern.

Zitat von Tropby:
Das ist mein OnData :
Delphi-Quellcode:
procedure TForm1.OnData(const aStream: TMemoryStream);
var header: TWaveHdr;
begin
  header.lpData := aStream.Memory;
  header.dwBufferLength := cWaveBufferSize;
  header.dwFlags := 0;
  waveOutPrepareHeader(fhandle, @header, cWaveBufferSize);
  waveOutWrite(fhandle, @header, cWaveBufferSize);
end;
Ich meine, genau da hakts, Editiere mal da alles raus, obs dann auch zu nem Fehler kommt, IMHO darfste genau das nicht machen.
  Mit Zitat antworten Zitat
zahor

 
Delphi 2007 Professional
 
#59
  Alt 7. Dez 2006, 17:15
Kann man auch den Soundkartenausgang "abhören", d.h. aufnehmen???
  Mit Zitat antworten Zitat
Benutzerbild von Sunlight7
Sunlight7

 
Delphi 5 Standard
 
#60
  Alt 7. Dez 2006, 17:51
Was meinst Du?
WaveOut?

Da kannst Du schon aufnehmen, Du brauchst nur die Quelle im Mixer einstellen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 6 von 10   « Erste     456 78     Letzte »    


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 20:52 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