Go to the documentation of this file.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::playBuffer(unsigned char * b, size_t s) {
00029 if (connection) {
00030 int error;
00031
00032 if (pa_simple_write(connection, b, s, &error) < 0) {
00033 fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n",
00034 pa_strerror(error));
00035 return;
00036 }
00037 }
00038 }
00039
00040 int SoundPlayer::getLatency() {
00041 if (connection) {
00042 int error;
00043 pa_usec_t ret = pa_simple_get_latency(connection, &error);
00044 return (int)ret;
00045 } else return 0;
00046 }
00047
00048
00049
00050
00051
00052
00053 SoundPlayer::SoundAction::SoundAction(SoundPlayer * a) {
00054 player = a;
00055 time = 0;
00056 latency = a ? a->getLatency() : 0;
00057 buffer = NULL;
00058 }
00059
00060 SoundPlayer::SoundAction::SoundAction(SoundPlayer * a, int t) {
00061 player = a;
00062 time = t;
00063 latency = a ? a->getLatency() : 0;
00064 buffer = NULL;
00065 }
00066
00067 SoundPlayer::SoundAction::SoundAction(const SoundPlayer::SoundAction & b) {
00068
00069 time = b.time;
00070 latency = b.latency;
00071 player = b.getPlayer();
00072 if (b.buffer) {
00073
00074 refCount = b.refCount;
00075 buffer = b.buffer;
00076 size = b.size;
00077 *refCount++;
00078 } else {
00079 buffer = NULL;
00080 }
00081 }
00082
00083
00084 SoundPlayer::SoundAction::~SoundAction() {
00085 if (buffer) {
00086 *refCount--;
00087 if (*refCount == 0) {
00088 delete refCount;
00089 delete[] buffer;
00090 }
00091 }
00092 }
00093
00094 void SoundPlayer::SoundAction::setWavFile(const char * f) {
00095
00096
00097 if (buffer) {
00098 *refCount--;
00099 if (*refCount == 0) {
00100 delete buffer;
00101 delete refCount;
00102 }
00103 buffer = NULL;
00104 }
00105
00106 filename = std::string(f);
00107 int fd;
00108
00109
00110 if ((fd = open(f, O_RDONLY)) < 0) {
00111 fprintf(stderr, __FILE__": open() failed: %s\n",
00112 strerror(errno));
00113 return;
00114 } else if (dup2(fd, STDIN_FILENO) < 0) {
00115 fprintf(stderr, __FILE__": dup2() failed: %s\n",
00116 strerror(errno));
00117 return;
00118 }
00119 close(fd);
00120
00121
00122 buffer = new unsigned char[BUFSIZE*2];
00123 int capacity = BUFSIZE*2;
00124 size = 0;
00125
00126 for (;;) {
00127 ssize_t r;
00128
00129
00130 if ((r = read(STDIN_FILENO, buffer + size, BUFSIZE)) <= 0) {
00131 if (r == 0) break;
00132 fprintf(stderr, __FILE__": read() failed: %s\n", strerror(errno));
00133 delete[] buffer; buffer = NULL;
00134 break;
00135 }
00136 size += r;
00137
00138
00139 if (size + BUFSIZE > capacity) {
00140
00141 int resize = capacity + (capacity > 1024*1024 ? 1024*1024 : capacity);
00142 unsigned char * tmp = new unsigned char[resize];
00143 memcpy(tmp, buffer, capacity); capacity = resize;
00144 delete[] buffer;
00145 buffer = tmp;
00146 }
00147 }
00148
00149
00150 if (buffer == NULL) return;
00151 refCount = new unsigned int;
00152 *refCount++;
00153 }
00154
00155
00156 void SoundPlayer::SoundAction::doAction() {
00157 if (buffer) {
00158 player->playBuffer(buffer, size);
00159 }
00160 }
00161
00162
00163