00001 #include <string>
00002 #include "audiere.h"
00003 #include "internal.h"
00004 #include "mci_device.h"
00005
00006
00007 namespace audiere {
00008
00013 static int g_song_count = 0;
00014
00015
00016 class MCIMIDIStream : public RefImplementation<MIDIStream>, public MCIDevice {
00017 public:
00018 static MCIMIDIStream* create(const char* filename) {
00019
00020 char alias[80];
00021 sprintf(alias, "adr_song_%d", g_song_count);
00022
00023 bool error;
00024 std::string result = sendString(
00025 std::string("open \"") + filename + "\" type sequencer alias " + alias,
00026 &error);
00027 if (error) {
00028 return 0;
00029 }
00030
00031 ++g_song_count;
00032 return new MCIMIDIStream(alias);
00033 }
00034
00035 MCIMIDIStream(const std::string& device)
00036 : MCIDevice(device)
00037 , m_repeat(false)
00038 {
00039 sendCommand("set", "time format milliseconds", MCI_WAIT);
00040 }
00041
00042 ADR_METHOD(void) play() {
00043 if (isPlaying()) {
00044 return;
00045 }
00046
00047 if (getPosition() == getLength()) {
00048 setPosition(0);
00049 }
00050 sendCommand("play", "", MCI_NOTIFY);
00051 }
00052
00053 ADR_METHOD(void) stop() {
00054 pause();
00055 setPosition(0);
00056 }
00057
00058 ADR_METHOD(void) pause() {
00059 sendCommand("stop");
00060 }
00061
00062 ADR_METHOD(bool) isPlaying() {
00063 return sendCommand("status", "mode") == "playing";
00064 }
00065
00066 ADR_METHOD(int) getLength() {
00067 return atoi(sendCommand("status", "length").c_str());
00068 }
00069
00070 ADR_METHOD(int) getPosition() {
00071 int pos = atoi(sendCommand("status", "position").c_str());
00072 int length = getLength();
00073 return (length == 0 ? pos : pos % length);
00074 }
00075
00076 ADR_METHOD(void) setPosition(int position) {
00077 bool playing = isPlaying();
00078
00079 char buffer[80];
00080 sprintf(buffer, "%d", position);
00081 sendCommand("seek", std::string("to ") + buffer, MCI_WAIT);
00082
00083 if (playing) {
00084 play();
00085 }
00086 }
00087
00088 ADR_METHOD(bool) getRepeat() {
00089 return m_repeat;
00090 }
00091
00092 ADR_METHOD(void) setRepeat(bool repeat) {
00093 m_repeat = repeat;
00094 }
00095
00096 protected:
00097 void notify(WPARAM flags) {
00098 if (flags == MCI_NOTIFY_SUCCESSFUL) {
00099 stop();
00100 if (m_repeat) {
00101 play();
00102 }
00103 }
00104 }
00105
00106 private:
00107 std::string m_device;
00108 bool m_repeat;
00109 };
00110
00111
00112 class MCIMIDIDevice : public RefImplementation<MIDIDevice> {
00113 public:
00114 ADR_METHOD(const char*) getName() {
00115 return "MCI";
00116 }
00117
00118 ADR_METHOD(MIDIStream*) openStream(const char* filename) {
00119 return MCIMIDIStream::create(filename);
00120 }
00121 };
00122
00123
00124 namespace hidden {
00125
00126 ADR_EXPORT(MIDIDevice*) AdrOpenMIDIDevice(const char* ) {
00127 return new MCIMIDIDevice;
00128 }
00129
00130 }
00131
00132 }