00001 #include "SoundPlayer.h"
00002
00005
00006
00007
00008
00009
00010 SoundPlayer::SoundPlayer() {
00011
00012 int error;
00013 static const pa_sample_spec ss = {PA_SAMPLE_S16LE, 24000, 1};
00014 if (!(connection = pa_simple_new(NULL, NULL, PA_STREAM_PLAYBACK, NULL,
00015 "playback", &ss, NULL, NULL, &error))) {
00016 fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n",
00017 pa_strerror(error));
00018 }
00019 }
00020
00021
00022 SoundPlayer::~SoundPlayer() {
00023 if (connection)
00024 pa_simple_free(connection);
00025 }
00026
00027
00028 void SoundPlayer::tagFrame(FCam::Frame *f) {
00029 if (!f) return;
00030 SoundPlayer::Tags * tags = new SoundPlayer::Tags;
00031
00032
00033 f->addTags(this, tags);
00034 }
00035
00036
00037 void SoundPlayer::playBuffer(unsigned char * b, size_t s) {
00038 if (connection) {
00039 int error;
00040
00041 if (pa_simple_write(connection, b, s, &error) < 0) {
00042 fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n",
00043 pa_strerror(error));
00044 return;
00045 }
00046 }
00047 }
00048
00049 int SoundPlayer::getLatency() {
00050 if (connection) {
00051 int error;
00052 pa_usec_t ret = pa_simple_get_latency(connection, &error);
00053 return (int)ret;
00054 } else return 0;
00055 }
00056
00057
00058
00059
00060
00061
00062 SoundPlayer::Tags::~Tags() {
00063
00064 }
00065
00066
00067
00068
00069
00070
00071 SoundPlayer::SoundAction::SoundAction(SoundPlayer * a) {
00072 player = a;
00073 time = 0;
00074 latency = a ? a->getLatency() : 0;
00075 buffer = NULL;
00076 }
00077
00078 SoundPlayer::SoundAction::SoundAction(SoundPlayer * a, int t) {
00079 player = a;
00080 time = t;
00081 latency = a ? a->getLatency() : 0;
00082 buffer = NULL;
00083 }
00084
00085 SoundPlayer::SoundAction::SoundAction(const SoundPlayer::SoundAction & b) {
00086
00087 time = b.time;
00088 latency = b.latency;
00089 player = b.getPlayer();
00090 if (b.buffer) {
00091
00092 refCount = b.refCount;
00093 buffer = b.buffer;
00094 size = b.size;
00095 *refCount++;
00096 } else {
00097 buffer = NULL;
00098 }
00099 }
00100
00101
00102 SoundPlayer::SoundAction::~SoundAction() {
00103 if (buffer) {
00104 *refCount--;
00105 if (*refCount == 0) {
00106 delete refCount;
00107 delete[] buffer;
00108 }
00109 }
00110 }
00111
00112 void SoundPlayer::SoundAction::setWavFile(const char * f) {
00113
00114
00115 if (buffer) {
00116 *refCount--;
00117 if (*refCount == 0) {
00118 delete buffer;
00119 delete refCount;
00120 }
00121 buffer = NULL;
00122 }
00123
00124 int fd;
00125
00126
00127 if ((fd = open(f, O_RDONLY)) < 0) {
00128 fprintf(stderr, __FILE__": open() failed: %s\n",
00129 strerror(errno));
00130 return;
00131 } else if (dup2(fd, STDIN_FILENO) < 0) {
00132 fprintf(stderr, __FILE__": dup2() failed: %s\n",
00133 strerror(errno));
00134 return;
00135 }
00136 close(fd);
00137
00138
00139 buffer = new unsigned char[BUFSIZE*2];
00140 int capacity = BUFSIZE*2;
00141 size = 0;
00142
00143 for (;;) {
00144 ssize_t r;
00145
00146
00147 if ((r = read(STDIN_FILENO, buffer + size, BUFSIZE)) <= 0) {
00148 if (r == 0) break;
00149 fprintf(stderr, __FILE__": read() failed: %s\n", strerror(errno));
00150 delete[] buffer; buffer = NULL;
00151 break;
00152 }
00153 size += r;
00154
00155
00156 if (size + BUFSIZE > capacity) {
00157
00158 int resize = capacity + (capacity > 1024*1024 ? 1024*1024 : capacity);
00159 unsigned char * tmp = new unsigned char[resize];
00160 memcpy(tmp, buffer, capacity); capacity = resize;
00161 delete[] buffer;
00162 buffer = tmp;
00163 }
00164 }
00165
00166
00167 if (buffer == NULL) return;
00168 refCount = new unsigned int;
00169 *refCount++;
00170 }
00171
00172
00173 void SoundPlayer::SoundAction::doAction() {
00174 if (buffer) {
00175 player->playBuffer(buffer, size);
00176 }
00177 }
00178
00179
00180