00001 #ifndef FILTERCONNECTION_H
00002 #define FILTERCONNECTION_H
00003 #include <stdio.h>
00004 #include <string>
00005 #include <vector>
00006 #include "Clock.h"
00007 #include "Connection.h"
00011 #define BUFFSIZE 256
00012
00025 template<class SAMPLE> class FilterConnection : private Connection<SAMPLE> {
00026 public:
00031 void connectFrom(Connection<SAMPLE> &conn) {
00032 connectFrom(&conn);
00033 }
00037 void connectFrom(Connection<SAMPLE> *conn) {
00038 if (conn->readable()) {
00039 inConnections.push_back(conn);
00040 } else {
00041 throw new string("Not A Input Connection");
00042 }
00043 }
00047 virtual void process() {
00048
00049 if (!writeReady()) {
00050 return;
00051 }
00052 int i =0;
00053 int c = 0;
00054 int size = inConnections.size();
00055 SAMPLE * b2 = buffer2;
00056 SAMPLE * b1 = buffer;
00057
00058 vector<Connection<SAMPLE>*>::iterator iter;
00059 for (i = 0; i < BUFFSIZE; i++ ) {
00060 b1[i] = 0;
00061 }
00062 for (iter = inConnections.begin(); iter < inConnections.end(); iter++) {
00063 if ((*iter)->readReady()) {
00064
00065 int r = (*iter)->read(b2,BUFFSIZE);
00066 if (r == -1) {
00067 disconnectFrom(*iter);
00068 } else {
00069 c++;
00070 for (i = 0; i < BUFFSIZE; i++ ) {
00071
00072 b1[i]+=(b2[i])/size;
00073
00074 }
00075 }
00076 }
00077 }
00078 if (c > 0) {
00079 write(b1,BUFFSIZE);
00080 }
00081 }
00082
00087 void disconnectFrom(Connection<SAMPLE> *conn) {
00088 vector<Connection<SAMPLE>*>::iterator iter;
00089 for (iter = inConnections.begin(); iter < inConnections.end(); iter++) {
00090 if (*iter == conn) {
00091 inConnections.erase(iter);
00092 break;
00093 }
00094 }
00095 }
00099 void disconnectTo(FilterConnection<SAMPLE> *conn){
00100 conn->disconnectFrom(this);
00101 }
00105 virtual string xmlType() {
00106 return "FILTER";
00107 }
00111 string * getXML() {
00112 char number[12];
00113 char number2[12];
00114 snprintf(number,12,"%d",this->getFileHandle());
00115 string * out = new string("<connection><type>");
00116 (*out)+=xmlType();
00117 (*out)+="</type><name>";
00118 (*out)+=getName();
00119 (*out)+="</name><id>";
00120 (*out)+=string(number);
00121 (*out)+="</id></connection>\n";
00122 vector<Connection<SAMPLE>*>::iterator iter;
00123 for (iter = inConnections.begin(); iter < inConnections.end(); iter++) {
00124 snprintf(number2,12,"%d",(*iter)->getFileHandle());
00125 (*out)+="<patch><from>";
00126 (*out)+=string(number2);
00127 (*out)+="</from><to>";
00128 (*out)+=string(number);
00129 (*out)+="</to></patch>";
00130 }
00131 return out;
00132 }
00136 int lastClock;
00137 virtual int read(SAMPLE * data, int size) {
00138 if (lastClock!=Clock::clock) {
00139 Connection<SAMPLE>::read(buffer3,size);
00140 lastClock=Clock::clock;
00141 }
00142 memcpy((void*)data,buffer3,sizeof(SAMPLE)*size);
00143 return size;
00144 }
00148 FilterConnection(BufferedFile * fd): inConnections() {
00149 init(fd,"Unnamed");
00150 initBuffer();
00151 }
00155 FilterConnection(BufferedFile * fd,string name): inConnections() {
00156 init(fd,name);
00157 initBuffer();
00158 }
00162 virtual ~FilterConnection() {
00163 if (!inConnections.empty()) {
00164 disconnect();
00165 }
00166 delete [] buffer;
00167 }
00168 protected:
00169 vector<Connection<SAMPLE>*> inConnections;
00170 SAMPLE * buffer;
00171 SAMPLE * buffer2;
00172 SAMPLE * buffer3;
00173 void initBuffer() {
00174
00175 buffer = new SAMPLE[3*BUFFSIZE];
00176 buffer2 = buffer+BUFFSIZE;
00177 buffer3= buffer2+BUFFSIZE;
00178 memset(buffer,0,BUFFSIZE);
00179 memset(buffer2,0,BUFFSIZE);
00180 memset(buffer3,0,BUFFSIZE);
00181 lastClock = 0;
00182 }
00183 virtual void disconnect() {
00184 inConnections.clear();
00185 this->Connection<SAMPLE>::disconnect();
00186 }
00187 private:
00188 };
00189 #endif