Programmieren mit C++

Code-Beispiele & Lösungen

Klassen für allgemeine Aufgaben

TMMPlayer – Basisklasse für MCI-Zugriffe

TMMPlayer ist eine Klasse zur Vereinfachung der Zugriffe auf das Windows-MCI-Interface. Die Funktionen der Klasse dienen vorwiegend der Statusabfrage, dem Setzen des Status und dem Abspielen. Aufnahmefähigkeiten werden nur für WAVE-Devices unterstützt. Für spezielle MCI-Geräte sollten entsprechende Klassen von dieser Basisklasse abgleitet werden.

Überblick

Zur zusätzlichen Steuerung werden der API-Funktion mciSendCommand bitcodierte Flags übergeben. TMMPlayer verwendet zwei dieser Flags:

  • MCI_WAIT
  • MCI_NOTIFY

Flags in TMMPlayer

Das Flag MCI_WAIT legt fest, daß Windows die Steuerung an die Applikation erst dann wieder zurückgibt, wenn das MCI-Kommando komplett abgearbeitet wurde. Per Vorgabe ist dieses Flag nicht gesetzt.

Flag MCI_WAIT

Das Flag MCI_NOTIFY weist Windows an, eine MM_MCINOTIFY-Nachricht zu versenden, wenn die veranlaßte MCI-Aktion beendet ist.

Aufgrund ihrer Eigenschaften entsprechen die beiden Flags den bei sndPlaySound möglichen Parametern:

  • SND_ASYNC
  • SND_SYNC

MCI_NOTIFY entspricht etwa dem SND_ASYNC-Parameter, während MCI_WAIT | MCI_NOTIFY mit SND_SYNC gleichgesetzt werden kann. Aus diesem Grund deklariert TMMPlayer zwei defines, die das Handling verkürzen und die Funktionalität verdeutlichen:

Flag MCI_NOTIFY

#define MM_ASYNC MCI_NOTIFY
#define MM_SYNC MCI_NOTIFY | MCI_WAIT 

Erfahrungen im Umgang mit dem MCI-Interface haben gezeigt, daß es sinnvoll ist, MCI_NOTIFY anzugeben, selbst dann, wenn MCI_WAIT unerwünscht ist. Wird kein Flag spezifiziert, lautet der entsprechende Parameter Null, was gelegentlich zu Komplikationen bei speziellen Treiber-/Hardware-Kombinationen führen kann.

defines für MCI-Flags

Das Kommando TMMPlayer::Play() setzt per Default die Flags MCI_WAIT | MCI_NOTIFY. Wenn MCI_WAIT unerwünscht ist, sollte man Play wie folgt aufrufen:

Play(MCI_NOTIFY);

Fehlerhandling

Standardaufruf

Per Vorgabe meldet TMMPlayer alle Fehler in einer Messagebox. Zusätzlich liefern fast alle Funktionen 0 als Ergebnis zurück, wenn der Aufruf erfolgreich abgearbeitet wurde, bzw. im Fall eines Fehlers den MCI-Fehlercode. Da die Anzeige einer Fehlermeldung nicht immer erwünscht sein mag, kann dieses Verhalten über eine spezielle Methode abgestellt oder aktiviert werden. SetErrorReporting(TRUE) aktiviert die Meldungsausgabe, während SetErrorReporting(FALSE) sie abschaltet.

Öffentliche Konstruktoren

TMMPlayer unterstützt zwei Formen des Konstruktors:

Fehlermeldung ausgeben

TMMPlayer(HWND hWnd, 
          const char* device, 
          BOOL errReporting);

Öffnet ein spezielles Gerät, dessen Bezeichnung in device übergeben wird. ErrReporting legt fest, ob Fehler per Messagebox angezeigt werden sollen (TRUE) oder nicht (FALSE).

Konstruktorform 1

TMMPlayer::TMMPlayer(HWND hWnd, 
                     const char* filename,
                     const char* device, 
                     DWORD flags, 
                     BOOL errReporting);

Die zweite Konstruktorform ist eine One-Step-Lösung. Der Konstruktur setzt das hWindow, öffnet die Datei filename und startet die Wiedergabe unter Beachtung der gesetzten Flagwerte in flags und des Fehlerstatus errReporting. Der Parameter für device kann normalerweise entfallen, da das MCI anhand der Dateiendung das korrekte Gerät erkennen kann.

Konstruktorform 2

close()

close schließt eine eventuell offene Datei und zerstört das Objekt.

Öffentliche Methoden

Destruktor

DWORD Open(const char* filename,
           const char* device = 0);
DWORD Open(const char* filename, 
           const char* device, 
           HWND parent, 
DWORD style);

Die erste Form der Methode Open öffnet ein Gerät mit einer Datei. Dabei kann der Parameter device NULL sein, wenn das MCI den Gerätetyp anhand der Dateiendung erkennen soll. Ist filenam NULL, wird lediglich das Gerät geöffnet.

Die zweite Form des Methodenaufrufs öffnet eine Datei und benutzt das Fenster parent für die Ausgabe der Datei. Dies ist vor allem für AVI-Video, Animationen und Video-Overlay-Geräte interessant.

Die Funktion liefert bei erfolgreichem Abarbeiten den Wert 0 zurück, ansonsten einen MCI-Fehlercode.

Methode Open

DWORD Close();

Schließt das Gerät und liefert 0 zurück, wenn kein Fehler auftrat, ansonsten resultiert ein MCI-Fehlercode.

Methode Close

DWORD Play(DWORD flags=MCI_NOTIFY| MCI_WAIT);
DWORD Play(const char* filename, 
           DWORD flags=MCI_NOTIFY| MCI_WAIT);
DWORD Play(DWORD from, 
           DWORD to, 
           DWORD flags=MCI_NOTIFY| MCI_WAIT);

Die Methode Play kennt drei Varianten:

  • Die erste Aufrufform startet die Wiedergabe des aktuell geöffneten Geräts.
  • Der zweite Aufruf öffnet eine Datei und beginnt die Wiedergabe, wobei der Gerätetyp automatisch anhand der Dateierweiterung bestimmt wird.
  • Die dritte Variante gibt die aktuell geladene Datei auf dem aktuellen Gerät von Position from bis to wieder.

Bei allen drei Wiedergabeformen werden die MCI-Flags in flags entsprechend berücksichtigt. Vorgabe ist MM_SYNC.

Bei erfolgreichem Abarbeiten liefert die Methode den Wert 0 zurück, ansonsten einen MCI-Fehlercode.

Methode Play

DWORD PlayResource(
      int resId, 
      HINSTANCE hInst, 
      UIN flags = SND_MEMORY | SND_SYNC |
                  SND_NODEFAULT);
DWORD PlayResource(
      const char* resName, 
      HINSTANCE hInst, 
      UINT flags = SND_MEMORY | SND_SYNC | 
                   SND_NODEFAULT);

Die erste Form des Aufrufs gibt eine Wave-Datei wieder, die aus den Ressourcen geladen wurde, deren Bezeichner ein Integerwert ist.

Die zweite Form des Aufrufs gibt eine Wave-Datei wieder, die aus den Ressourcen geladen wurde, deren Bezeichner eine Stringkonstante ist.

Methode PlayResource

DWORD Record(DWORD flags = MCI_NOTIFY | 
                       MCI_RECORD_OVERWRITE);
DWORD Record(DWORD from, 
             DWORD to, 
             DWORD flags = MM_SYNC | 
                       MCI_RECORD_OVERWRITE);

Auch für das Aufnehmen von Wave-Dateien gibt es zwei Aufrufkonventionen. Die erste Form beginnt unmittelbar nach dem Methodenaufruf mit der Aufnahme und gibt die Kontrolle an die Anwendung zurück. Beendet wird die Aufnahme durch den Methodenaufruf Stop().

Die zweite Aufrufvariante beginnt die Aufnahme an Position from und endet bei to. Die Methode gibt die Kontrolle erst dann wieder an die Anwendung zurück, wenn die Aufnahme beendet ist.

Methode Record

Um 5 Sekunden aufzuzeichnen, kann beispielsweise der nachfolgende Aufruf verwendet werden.

Record(0, 5000)

Per Vorgabe werden vorhandene Daten überschrieben. Sollen hingegen 5 Sekunden an Position 2000 in die vorhandenen Daten eingefügt werden, muß folgender Aufruf erfolgen:

Beispiel zu Record

Record(2000, 7000, 
       MM_SYNC | MCI_RECORD_INSERT)
DWORD Save(const char* filename = 0, 
           DWORD flags = MCI_SAVE_FILE | 
                         MCI_WAIT);

Save speichert aufgezeichnete oder veränderte Daten in die Datei filename. Wird kein Dateiname angegeben, verwendet die Methode die Datei, mit der das Gerät geöffnet wurde.

Methode Save

DWORD Load(const char* filename = 0, 
           DWORD flags = MCI_LOAD_FILE | 
                         MCI_WAIT);

Load lädt die Datei filename explizit in den Speicher, bevor weitere MCI-Aktionen erfolgen. Üblicherweise folgt anschließend eine Wiedergabe mit Play() oder eine Bearbeitung der Daten.

Es ist bekannt, daß nicht jeder Treiber diesen Aufruf korrekt abarbeitet.

Methode Load

DWORD Delete(DWORD from = 0, 
             DWORD to = 0);

Mit Delete werden die aktuellen Daten von Position from bis to gelöscht.

Methode Delete

DWORD Stop();

Stop beendet eine Aufnahme, die zuvor mit Record() gestartet wurde, oder eine mittels Play() begonnene Wiedergabe. Im Gegensatz zu der Methode Pause(), die den aktuellen Vorgang lediglich anhält, sendet das MCI nach Durchführen der Funktion Stop eine MCI_NOTIFY Nachricht.

Methode Stop

DWORD Pause(DWORD flags = MCI_WAIT);

Pause unterbricht eine Aufnahme oder Wiedergabe, ohne daß eine MCI_NOTIFY-Nachricht versendet wird.

Methode Pause

DWORD Resume();

Resume() führt die durch Pause() unterbrochene Aktion, die entweder eine Aufnahme oder eine Wiedergabe war, fort. Es wird dabei keine MCI_NOTIFY Nachricht versendet.

Methode Resume

DWORD Seek(DWORD to = 0, 
           DWORD flags = MCI_SEEK_TO_START);

Mit Seek() wird der Positionszeiger auf die Position to gesetzt. Wird kein Parameter übergeben, setzt das MCI die Position auf den Beginn der Daten.

Methode Seek

DWORD Erase();

Erase() löscht alle daten des Geräts über einen Aufruf von Delete().

Methode Erase

DWORD Rewind();

Nach einem Abspielen ist ein Rewind() erforderlich, um das Abspielen vom Beginn erneut starten zu können. Anstelle on Rewind() könnte man auch Seek() ohne jeden Parameter verwenden. Rewind() wird trotzdem unterstützt, um die korrekte Zuordnung der Methoden zum MCI zu gewährleisten.

Methode Rewind

DWORD FastForward();

FastForward() setzt den aktuellen Positionszeiger auf das Ende der Daten. Auch dieser Aufruf könnte über Seek() simuliert werden. Ein separater Aufruf mit wohldefinierter Funktionalität ist aber sinnvoller.

Methode FastForward

DWORD Copy(DWORD flags = MCI_WAIT);

Copy kopiert die Daten des Geräts in die Zwischenablage.

Viele Geräte bzw. Treiber unterstützen diese Funktion nicht.

Methode Copy

DWORD Cut(DWORD flags = 0);

Cut führt die Operation „Ausschneiden“ auf die aktuellen Daten aus, indem diese in die Zwischenablage verschoben werden.

Viele Geräte bzw. Treiber unterstützen diese Funktion nicht.

Methode Cut

DWORD Paste(DWORD flags = 0);

Paste fügt den Inhalt der Zwischenablage im Datenbereich des aktuellen Geräts ein.

Viele Geräte bzw. Treiber unterstützen diese Funktion nicht.

Methode Paste

DWORD GetDeviceCaps(DWORD item);

GetDeviceCaps() ermittelt die Fähigkeiten des aktuellen Geräts. In item muß die interessierende Fähigkeit als MCI-Konstante übergeben werden. Das Funktionsergebnis lautet TRUE, wenn das Gerät die Fähigkeit unterstützt, ansonsten FALSE.

Methode GetDeviceCaps

BOOL CanEject();

CanEject liefert TRUE, wenn das Gerät das Medium auswerfen kann, ansonsten FALSE.

Methode CanEject

BOOL CanPlay();

CanPlay() liefert TRUE, wenn das Gerät ein Medium abspielen kann, ansonsten FALSE.

Methode CanPlay

BOOL CanRecord();

CanRecord() liefert TRUE, wenn das Gerät aufnehmen kann, ansonsten wird FALSE returniert.

Methode CanRecord

BOOL CanSave();

CanSave liefert TRUE, wenn das Gerät Daten speichern kann, ansonsten FALSE.

Methode CanSave

BOOL HasAudio();

HasAudio() returniert TRUE, wenn das Gerät AudioOut-Fähigkeiten besitzt, ansonsten resultiert FALSE.

Methode HasAudio

BOOL HasVideo();

HasVideo liefert TRUE, wenn das Gerät Video-Ausgabe-Fähigkeiten besitzt, ansonsten FALSE.

Methode HasVideo

BOOL UsesFiles();

UsesFiles() liefert TRUE, wenn das Gerät Dateinamen verwendet, ansonsten FALSE.

Methode UsesFiles

DWORD GetStatusItem(DWORD item);

GetStatusItem() liefert den aktuellen Status bezüglich des in item übergebenen Status-Attributs.

Methode GetStatusItem

BOOL IsOpen();

IsOpen() liefert als Funktionsergebnis TRUE, wenn das Gerät geöffnet wurde, ansonsten FALSE.

Methode IsOpen

BOOL IsReady();

IsReady() returniert TRUE, wenn das Gerät für Ein- oder Ausgaben bereit ist, ansonsten FALSE.

Methode IsReady

DWORD IsMediaPresent();

IsMediaPresent() gibt TRUE zurück, wenn im Gerät ein Medium eingelegt ist, ansonsten FALSE. Diese Fähigkeit wird üblicherweise nur von Player für Audio-CD und Video-Disk unterstützt.

Methoden IsMediaPresent

DWORD GetSysInfoItem(DWORD item, 
                     char* info, 
                     int dev);

GetSysInfoItem() liefert die System-Informationen zum übergebenen Attribut item. Wurde die Funktion korrekt abgearbeitet, lautet das Funktionsergebnis 0, ansonsten gibt es einen MCI-Fehlercode wieder.

Methode GetSysInfoItem

DWORD GetInfoItem(DWORD item, 
                  char* info);

GetInfoItem() liefert Informationen über das Attribut item. Wurde die Funktion korrekt abgearbeitet, lautet das Funktionsergebnis 0, ansonsten gibt es einen MCI-Fehlercode wieder.

Methode GetInfoItem

DWORD GetDeviceName(char* name);

GetDeviceName ermittelt den Gerätenamen, der vom Gerätehersteller gesetzt wurde und über das MCI erfragt werden kann.

Methode GetDeviceName

DWORD GetDeviceType();

GetDeviceType() liefert den Typ des Geräts zurück. Mögliche Werte sind:

Methode GetDeviceType

  • MCI_DEVTYPE_ANIMATION
  • MCI_DEVTYPE_CD_AUDIO
  • MCI_DEVTYPE_DAT
  • MCI_DEVTYPE_DIGITAL_VIDEO
  • MCI_DEVTYPE_OTHER
  • MCI_DEVTYPE_OVERLAY
  • MCI_DEVTYPE_SCANNER
  • MCI_DEVTYPE_SEQUENCER
  • MCI_DEVTYPE_VIDEODISC
  • MCI_DEVTYPE_VCR
  • MCI_DEVTYPE_WAVEFORM_AUDIO

Gerätekonstanten

DWORD GetFileName(char* filename);

GetFileName() liefert den Namen der aktuell vom Gerät verwendeten Datei. Diese Funktion kann nur mit Geräten eingesetzt werden, die auch Dateien verwenden können. Diese Eigenschaft kann mit der Methode UsesFile() überprüft werden. Wurde die Funktion korrekt abgearbeitet, lautet das Funktionsergebnis 0, ansonsten gibt es einen MCI-Fehlercode wieder.

Methode GetFileName

DWORD GetPosition();

GetPosition ermittelt die aktuelle Position des MCI-internen Zeigers auf die Daten des Geräts.

Methode GetPosition

DWORD GetLength();

GetLength() liefert die Länge des aktuellen in das Gerät geladenen Mediums. Für Wave Audio ist dieser Wert per default als Millisekunden zu interpretieren; für AVI Video werden Frames zurückgeliefert.

Methode GetLength

DWORD GetMode();

GetMode() kann mit GetStatus() geleichgesetzt werden.

Methode GetMode

DWORD GetStatus();

GetStatus() ermittelt den aktuellen Status des Geräts. Zurückgeliefert wird der Status in Form eines MCI-Codes. Möglich sind:

  • MCI_MODE_NOT_READY
  • MCI_MODE_PAUSE
  • MCI_MODE_PLAY
  • MCI_MODE_STOP
  • MCI_MODE_OPEN
  • MCI_MODE_RECORD
  • MCI_MODE_SEEK

Methode GetStatus

DWORD GetTimeFormat();

Mit der Methode GetTimeFormat() kann das aktuell gesetzte Zeitformat ermittelt werden. Mögliche Rückgabewerte sind:

  • MCI_FORMAT_BYTES
  • MCI_FORMAT_FRAMES
  • MCI_FORMAT_HMS
  • MCI_FORMAT_MILLISECONDS
  • MCI_FORMAT_MSF
  • MCI_FORMAT_SAMPLES
  • MCI_FORMAT_TMSF

Methode GetTimeFormat

DWORD GetVolume();

GetVolume() ermittelt die aktuelle Lautstärke für Audio-fähige Geräte. Das höherwertige Wort liefert den Wert für den rechten Kanal, während das niederwertige Wort den Wert für den linken Kanal enthält.

Methode GetVolume

DWORD Set(DWORD flags, 
          DWORD options = 0);

Set() setzt die in flags übergebenen Attribute. Mögliche Werte sind der Dokumentation des jeweiligen Treibers zu entnehmen.

Methode Set

DWORD SetAudioOff();

Schaltet die Audio-Ausgabe des Geräts ab.

Methode SetAudioOff

DWORD SetAudioOn();

SetAudioOn() aktiviert die Audio-Ausgabe.

Methode SetAudioOn

DWORD SetTimeFormat(DWORD format);

Mit der Methode SetTimeFormat() kann ein neues Zeitformat für das Gerät festgelegt werden.

Methode SetTimeFormat

DWORD SetVideoOff();

SetVideoOff() schaltet die Video-Ausgabe des Geräts ab.

Methode SetVideoOff

DWORD SetVideoOn();

SetVideoOn() aktiviert die Videoausgabe des Geräts.

Methode SetVideoOn

DWORD SetPosition(DWORD position);

SetPosition() setzt eine neue aktuelle Position für den MCI-internen Positionszeiger. Bei erfolgreichem Abarbeiten der Funktion wird 0 zurückgeliefert, ansonsten ein MCI-Fehlercode.

Methode SetPosition

void SetCallbackWindow(HWND hWnd);

Mit SetCallbackWindow() wird das Objektdatenfeld hWnd besetzt. Dieses Fenster enthält alle Callback-Nachrichten, wenn MCI_NOTIFY oder MM_ASYNC gesetzt wurden. Die Funktion verhält sich analog zu SetParent().

Methode SetCallbackWindow

void SetParent(HWND hWnd);

SetParanet() setzt das Objektdatenfeld hWnd, das alle Benachrichtigungen des MCI erhält. Die Methode verhält sich wie SetCallbackWindow() und ist nur der Vollständigkeit enthalten.

Methode SetParent

DWORD SetVolume(int volume);
DWORD SetVolume(int lvol, int rvol);

Das Setzen der Lautstärke über SetVolume() kennt zwei Aufrufkonventionen. Die erste gezeigte Variante setzt eine Lautstärke mit einem Ausruf für beide Kanäle gleichzeitig, während die zweite Variante eine getrennte Zuweisung für beide Kanäle unterstützt. Der Wert der Lautstärke ist als Prozentwert im Bereich 0–100 zu spezifizieren.

Methode SetVolume

void SetErrorReporting(BOOL err);

SetErrorReporting() steuert das interne Messagehandling im Fall von Fehlern. Mit err = TRUE werden automatisch Fehlermeldungen ausgegeben, die mit err = FALSE abgeschaltet werden.

Methode SetErrorReporting

void SetYieldProc(BOOL enabled, 
                  DWORD data = 0, 
                  BOOL msgLoop = FALSE);

SetYieldProc() aktiviert oder deaktiviert eine Callback-Funktion, die periodisch während der Abarbeitung des MCI-Kommandos aufgerufen wird, das mit MCI_WAIT bzw. MM_SYNC gestartet wurde. In data werden Daten übergeben, die anschließend an die Yield-Funktion weitergeleitet werden. msgLoop legt fest, ob im Yield-Prozeß eine Nachrichtenbearbeitungsschleife benutzt werden soll oder nicht. Der abzuarbeitende Code muß in der abzuleitenden Methode YieldProcess() integriert werden.

Methode SetYieldProc

virtual BOOL YieldProcess(UINT devID, 
                          DWORD data);

Diese Funktion muß überschrieben werden, wenn eine individuelle Yield-Funktion verwendet werden soll.

TMMPlayer in der Praxis

Die nachfolgenden Beispielcodes zeigen, wie mit TMMPlayer komfortabel Aufgaben gelöst werden.

//Object konstruieren
TMMPlayer Player(HWindow);
 
//Datei öffnen
Player.Open(“sound.wav”);
 
//Wiedergabe mit Default-Flags
Player.Play();
 
//zurücksetzen und erneut spielen
Player.Rewind();
Player.Play();
 
//Länge der Datei in Millisekunden
DWORD length = Player.GetMediaLength();
DWORD pos = length/2;
 
//Wiedergabe ab Mitte der Datei
Player.SetPosition(pos);
Player.Play();
 
//erste Hälfte wiedergeben
Player.Play(0, pos);
Player.Close();
 
//Datei zu Aufnehmen öffnen
Player.Open(“”, “waveaudio”);
 
//zwei Sekunden aufnehmen und speichern
Player.Record(0, 2000);
Player.Save(“test.wav”);
 
//zurücksetzen und abspielen
Player.Rewind();
Player.Play();

Methode YieldProcess





Sachgebiet


© 2009-2012 by Alojado Publishing. Alle Rechte vorbehalten. Ausgewiesene Marken gehören ihren jeweiligen Eigentümern.
Mit der Benutzung dieser Seite erkennen Sie die Nutzungsbedingungen und die Datenschutzerklärung an. Der Betreiber übernimmt keine Haftung für den Inhalt verlinkter externer Internetseiten.
Seite erzeugt 2012-05-20 03:23:58 von textarchiv.alojado.de