00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "mainvisual.h"
00010 #include "synaesthesia.h"
00011
00012 #include <qpainter.h>
00013 #include <qpixmap.h>
00014 #include <qimage.h>
00015
00016 #include <math.h>
00017 #include <stdlib.h>
00018
00019 #include "config.h"
00020 #ifdef HAVE_STDINT_H
00021 #include <stdint.h>
00022 #endif
00023
00024 #include <inttypes.h>
00025
00026 #include <iostream>
00027 using namespace std;
00028
00029 #include <mythtv/compat.h>
00030
00031 Synaesthesia::Synaesthesia(long int winid)
00032 {
00033 fps = 29;
00034 fadeMode = Stars;
00035 pointsAreDiamonds = true;
00036 energy_avg = 80.0;
00037
00038 coreInit();
00039 starSize = 0.5;
00040 setStarSize(starSize);
00041 brightnessTwiddler = 0.3;
00042 outputImage = NULL;
00043 fgRedSlider = 0.0;
00044 fgGreenSlider = 0.5;
00045 bgRedSlider = 0.75;
00046 bgGreenSlider = 0.4;
00047
00048 #ifdef SDL_SUPPORT
00049 surface = NULL;
00050
00051 char SDL_windowhack[32];
00052 sprintf(SDL_windowhack, "%ld", winid);
00053 setenv("SDL_WINDOWID", SDL_windowhack, 1);
00054
00055 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0)
00056 {
00057 cerr << "Unable to init SDL\n";
00058 return;
00059 }
00060
00061 SDL_ShowCursor(0);
00062 #endif
00063
00064 setupPalette();
00065 }
00066
00067 Synaesthesia::~Synaesthesia()
00068 {
00069 if (outputImage)
00070 delete outputImage;
00071 #ifdef SDL_SUPPORT
00072 SDL_Quit();
00073 unsetenv("SDL_WINDOWID");
00074 #endif
00075 }
00076
00077 void Synaesthesia::setupPalette(void)
00078 {
00079 #define sBOUND(x) ((x) > 255 ? 255 : (x))
00080 #define sPEAKIFY(x) int(sBOUND((x) - (x)*(255-(x))/255/2))
00081 #define sMAX(x,y) ((x) > (y) ? (x) : (y))
00082 int i;
00083 double scale, fgRed, fgGreen, fgBlue, bgRed, bgGreen, bgBlue;
00084 fgRed = fgRedSlider;
00085 fgGreen = fgGreenSlider;
00086 fgBlue = 1.0 - sMAX(fgRedSlider,fgGreenSlider);
00087
00088 scale = (fgRed + fgGreen + fgBlue) / 2.0;
00089 fgRed /= scale;
00090 fgGreen /= scale;
00091 fgBlue /= scale;
00092
00093 bgRed = bgRedSlider;
00094 bgGreen = bgGreenSlider;
00095 bgBlue = 1.0 - sMAX(bgRedSlider,bgGreenSlider);
00096
00097 scale = (bgRed + bgGreen + bgBlue) / 2.0;
00098 bgRed /= scale;
00099 bgGreen /= scale;
00100 bgBlue /= scale;
00101
00102 for (i = 0; i < 256; i++) {
00103 int f = i & 15, b = i / 16;
00104
00105
00106
00107
00108 double red = b * bgRed * 16 + f * fgRed * 16;
00109 double green = b * bgGreen * 16 + f * fgGreen * 16;
00110 double blue = b * bgBlue * 16 + f * fgBlue * 16;
00111
00112 double excess = 0.0;
00113 for (int j = 0; j < 5; j++)
00114 {
00115 red += excess / 3;
00116 green += excess / 3;
00117 blue += excess / 3;
00118 excess = 0.0;
00119
00120
00121 if (red > 255) { excess += red - 255; red = 255; }
00122 if (green > 255) { excess += green - 255; green = 255; }
00123 if (blue > 255) { excess += blue - 255; blue = 255; }
00124 }
00125
00126 double scale = (0.5 + (red + green + blue) / 768.0) / 1.5;
00127 red *= scale;
00128 green *= scale;
00129 blue *= scale;
00130
00131 palette[i * 3 + 0] = sBOUND(int(red));
00132 palette[i * 3 + 1] = sBOUND(int(green));
00133 palette[i * 3 + 2] = sBOUND(int(blue));
00134 }
00135 }
00136
00137 void Synaesthesia::resize(const QSize &newsize)
00138 {
00139 size = newsize;
00140
00141 size.setHeight(size.height() / 2);
00142 size.setWidth((size.width() / 4) * 4);
00143 outputBmp.size(size.width(), size.height());
00144 lastOutputBmp.size(size.width(), size.height());
00145 lastLastOutputBmp.size(size.width(), size.height());
00146 outWidth = size.width();
00147 outHeight = size.height();
00148
00149 if (outputImage)
00150 delete outputImage;
00151
00152 size.setHeight(size.height() * 2);
00153 outputImage = new QImage(size, 8, 256);
00154
00155 if (!outputImage)
00156 {
00157 cerr << "outputImage in Synaesthesia::resize() is NULL" << endl;
00158 return;
00159 }
00160
00161 for (int i = 0; i < 256; i++)
00162 outputImage->setColor(i, qRgb(palette[i * 3], palette[i * 3 + 1],
00163 palette[i * 3 + 2]));
00164
00165 #ifdef SDL_SUPPORT
00166 surface = SDL_SetVideoMode(size.width(), size.height(), 8, 0);
00167
00168 if (!surface)
00169 {
00170 cerr << "Couldn't get SDL surface\n";
00171 return;
00172 }
00173
00174 SDL_Color sdlPalette[256];
00175
00176 for (int i = 0; i < 256; i++)
00177 {
00178 sdlPalette[i].r = palette[i * 3];
00179 sdlPalette[i].g = palette[i * 3 + 1];
00180 sdlPalette[i].b = palette[i * 3 + 2];
00181 }
00182
00183 SDL_SetColors(surface, sdlPalette, 0, 256);
00184 #endif
00185 }
00186
00187 int Synaesthesia::bitReverser(int i)
00188 {
00189 int sum = 0;
00190 for (int j = 0; j < LogSize; j++)
00191 {
00192 sum = (i & 1) + sum * 2;
00193 i >>= 1;
00194 }
00195
00196 return sum;
00197 }
00198
00199 void Synaesthesia::fft(double *x, double *y)
00200 {
00201 int n2 = NumSamples, n1;
00202 for (int twoToTheK = 1; twoToTheK < NumSamples; twoToTheK *= 2)
00203 {
00204 n1 = n2;
00205 n2 /= 2;
00206 for (int j = 0; j < n2; j++)
00207 {
00208 double c = cosTable[j * twoToTheK & (NumSamples - 1)],
00209 s = negSinTable[j * twoToTheK & (NumSamples - 1)];
00210 for (int i = j; i < NumSamples; i += n1)
00211 {
00212 int l = i + n2;
00213 double xt = x[i] - x[l];
00214 x[i] = (x[i] + x[l]);
00215 double yt = y[i] - y[l];
00216 y[i] = (y[i] + y[l]);
00217 x[l] = xt * c - yt * s;
00218 y[l] = xt * s + yt * c;
00219 }
00220 }
00221 }
00222 }
00223
00224 void Synaesthesia::setStarSize(double lsize)
00225 {
00226 double fadeModeFudge = (fadeMode == Wave ? 0.4 :
00227 (fadeMode == Flame ? 0.6 : 0.78));
00228
00229 int factor;
00230 if (lsize > 0.0)
00231 factor = int(exp(log(fadeModeFudge) / (lsize * 8.0)) * 255);
00232 else
00233 factor = 0;
00234
00235 if (factor > 255)
00236 factor = 255;
00237
00238 for (int i = 0; i < 256; i++)
00239 scaleDown[i] = i * factor>>8;
00240
00241 maxStarRadius = 1;
00242 for (int i = 255; i; i = scaleDown[i])
00243 maxStarRadius++;
00244 }
00245
00246 void Synaesthesia::coreInit(void)
00247 {
00248 for (int i = 0; i < NumSamples; i++)
00249 {
00250 negSinTable[i] = -sin(3.141592 * 2.0 / NumSamples * i);
00251 cosTable[i] = cos(3.141592 * 2.0 / NumSamples * i);
00252 bitReverse[i] = bitReverser(i);
00253 }
00254 }
00255
00256 #define output ((unsigned char*)outputBmp.data)
00257 #define lastOutput ((unsigned char*)lastOutputBmp.data)
00258 #define lastLastOutput ((unsigned char*)lastLastOutputBmp.data)
00259
00260 void Synaesthesia::addPixel(int x, int y, int br1, int br2)
00261 {
00262 if (x < 0 || x > outWidth || y < 0 || y >= outHeight)
00263 return;
00264
00265 unsigned char *p = output + x * 2 + y * outWidth * 2;
00266 if (p[0] < 255 - br1)
00267 p[0] += br1;
00268 else
00269 p[0] = 255;
00270 if (p[1] < 255 - br2)
00271 p[1] += br2;
00272 else
00273 p[1] = 255;
00274 }
00275
00276 void Synaesthesia::addPixelFast(unsigned char *p, int br1, int br2)
00277 {
00278 if (p[0] < 255 - br1)
00279 p[0] += br1;
00280 else
00281 p[0] = 255;
00282 if (p[1] < 255 - br2)
00283 p[1] += br2;
00284 else
00285 p[1] = 255;
00286 }
00287
00288 unsigned char Synaesthesia::getPixel(int x, int y, int where)
00289 {
00290 if (x < 0 || y < 0 || x >= outWidth || y >= outHeight)
00291 return 0;
00292
00293 return lastOutput[where];
00294 }
00295
00296 void Synaesthesia::fadeFade(void)
00297 {
00298 register uint32_t *ptr = (uint32_t *)output;
00299 int i = outWidth * outHeight * 2 / sizeof(uint32_t);
00300 do {
00301 uint32_t x = *ptr;
00302 if (x)
00303 *(ptr++) = x - ((x & (uintptr_t)0xf0f0f0f0) >> 4) -
00304 ((x & (uintptr_t)0xe0e0e0e0) >> 5);
00305 else
00306 ptr++;
00307 } while (--i > 0);
00308 }
00309
00310 void Synaesthesia::fadePixelWave(int x, int y, int where, int step)
00311 {
00312 short j = (short(getPixel(x - 1, y, where - 2)) +
00313 getPixel(x + 1, y, where + 2) +
00314 getPixel(x, y - 1, where - step) +
00315 getPixel(x, y + 1, where + step) >> 2) + lastOutput[where];
00316 if (!j)
00317 {
00318 output[where] = 0;
00319 return;
00320 }
00321 j = j - lastLastOutput[where] - 1;
00322 if (j < 0)
00323 output[where] = 0;
00324 else if (j & (255 * 256))
00325 output[where] = 255;
00326 else
00327 output[where] = j;
00328 }
00329
00330 void Synaesthesia::fadeWave(void)
00331 {
00332 unsigned short *t = lastLastOutputBmp.data;
00333 lastLastOutputBmp.data = lastOutputBmp.data;
00334 lastOutputBmp.data = outputBmp.data;
00335 outputBmp.data = t;
00336
00337 int x, y, i, j, start, end;
00338 int step = outWidth*2;
00339 for (x = 0, i = 0, j = outWidth * (outHeight - 1) * 2;
00340 x < outWidth; x++, i += 2, j += 2)
00341 {
00342 fadePixelWave(x, 0, i, step);
00343 fadePixelWave(x, 0, i + 1, step);
00344 fadePixelWave(x, outHeight - 1, j, step);
00345 fadePixelWave(x, outHeight - 1, j + 1, step);
00346 }
00347
00348 for (y = 1, i = outWidth * 2, j = outWidth * 4 - 2;
00349 y < outHeight; y++, i += step, j += step)
00350 {
00351 fadePixelWave(0, y, i, step);
00352 fadePixelWave(0, y, i + 1, step);
00353 fadePixelWave(outWidth - 1, y, j, step);
00354 fadePixelWave(outWidth - 1, y, j + 1, step);
00355 }
00356
00357 for (y = 1, start = outWidth * 2 + 2, end = outWidth * 4 - 2;
00358 y < outHeight - 1; y++, start += step, end += step)
00359 {
00360 int i = start;
00361 do {
00362 short j = (short(lastOutput[i - 2]) + lastOutput[i + 2] +
00363 lastOutput[i - step] +
00364 lastOutput[i + step] >> 2) + lastOutput[i];
00365 if (!j) {
00366 output[i] = 0;
00367 } else {
00368 j = j - lastLastOutput[i] - 1;
00369 if (j < 0)
00370 output[i] = 0;
00371 else if (j & (255*256))
00372 output[i] = 255;
00373 else
00374 output[i] = j;
00375 }
00376 } while(++i < end);
00377 }
00378 }
00379
00380 void Synaesthesia::fadePixelHeat(int x, int y, int where, int step)
00381 {
00382 short j = (short(getPixel(x - 1, y, where - 2)) +
00383 getPixel(x + 1, y, where + 2) +
00384 getPixel(x, y - 1, where - step) +
00385 getPixel(x, y + 1, where + step) >> 2) + lastOutput[where];
00386 if (!j)
00387 {
00388 output[where] = 0;
00389 return;
00390 }
00391 j = j -lastLastOutput[where] - 1;
00392 if (j < 0)
00393 output[where] = 0;
00394 else if (j & (255 * 256))
00395 output[where] = 255;
00396 else
00397 output[where] = j;
00398 }
00399
00400 void Synaesthesia::fadeHeat(void)
00401 {
00402 unsigned short *t = lastLastOutputBmp.data;
00403 lastLastOutputBmp.data = lastOutputBmp.data;
00404 lastOutputBmp.data = outputBmp.data;
00405 outputBmp.data = t;
00406
00407 int x, y, i, j, start, end;
00408 int step = outWidth * 2;
00409 for (x = 0, i = 0, j = outWidth * (outHeight - 1) * 2;
00410 x < outWidth; x++, i += 2, j += 2)
00411 {
00412 fadePixelHeat(x, 0, i, step);
00413 fadePixelHeat(x, 0, i + 1, step);
00414 fadePixelHeat(x, outHeight - 1, j, step);
00415 fadePixelHeat(x, outHeight - 1, j + 1, step);
00416 }
00417
00418 for(y = 1, i = outWidth * 2, j = outWidth * 4 - 2; y < outHeight;
00419 y++, i += step, j += step)
00420 {
00421 fadePixelHeat(0, y, i, step);
00422 fadePixelHeat(0, y, i + 1, step);
00423 fadePixelHeat(outWidth - 1, y, j, step);
00424 fadePixelHeat(outWidth - 1, y, j + 1, step);
00425 }
00426
00427 for(y = 1, start = outWidth * 2 + 2, end = outWidth * 4 - 2;
00428 y < outHeight - 1; y++, start += step, end += step)
00429 {
00430 int i = start;
00431 do {
00432 short j = (short(lastOutput[i - 2]) + lastOutput[i + 2] +
00433 lastOutput[i - step] + lastOutput[i + step] >> 2) +
00434 lastOutput[i];
00435 if (!j)
00436 output[i] = 0;
00437 else
00438 {
00439 j = j - lastLastOutput[i] +
00440 (lastLastOutput[i] - lastOutput[i] >> 2) - 1;
00441 if (j < 0)
00442 output[i] = 0;
00443 else if (j & (255*256))
00444 output[i] = 255;
00445 else
00446 output[i] = j;
00447 }
00448 } while(++i < end);
00449 }
00450 }
00451
00452 void Synaesthesia::fade(void)
00453 {
00454 switch(fadeMode) {
00455 case Stars: fadeFade(); break;
00456 case Flame: fadeHeat(); break;
00457 case Wave: fadeWave(); break;
00458 default: break;
00459 }
00460 }
00461
00462 bool Synaesthesia::process(VisualNode *node)
00463 {
00464 fade();
00465
00466 if (!node)
00467 return true;
00468
00469 double x[NumSamples], y[NumSamples];
00470 double a[NumSamples], b[NumSamples];
00471 double energy;
00472 int clarity[NumSamples];
00473 int i, j, k;
00474
00475 int brightFactor = int(Brightness * brightnessTwiddler / (starSize + 0.01));
00476
00477 int numSamps = NumSamples;
00478 if (node->length < NumSamples)
00479 numSamps = node->length;
00480
00481 memset(x, 0, sizeof(x));
00482 memset(y, 0, sizeof(y));
00483
00484 for (i = 0; i < numSamps; i++)
00485 {
00486 x[i] = node->left[i];
00487 if (node->right)
00488 y[i] = node->right[i];
00489 else
00490 y[i] = x[i];
00491 }
00492
00493 fft(x, y);
00494
00495 energy = 0.0;
00496
00497 for (i = 0 + 1; i < NumSamples / 2; i++)
00498 {
00499 double x1 = x[bitReverse[i]],
00500 y1 = y[bitReverse[i]],
00501 x2 = x[bitReverse[NumSamples - i]],
00502 y2 = y[bitReverse[NumSamples - i]],
00503 aa, bb;
00504 a[i] = sqrt(aa = (x1 + x2) * (x1 + x2) + (y1 - y2) * (y1 - y2));
00505 b[i] = sqrt(bb = (x1 - x2) * (x1 - x2) + (y2 + y2) * (y1 + y2));
00506 if (aa + bb != 0.0)
00507 clarity[i] = (int)(((x1 + x2) * (x1 - x2) + (y1 + y2) * (y1 - y2)) /
00508 (aa + bb) * 256);
00509 else
00510 clarity[i] = 0;
00511
00512 energy += (aa + bb) * i * i;
00513 }
00514
00515 energy = sqrt(energy / NumSamples) / 65536.0;
00516
00517
00518
00519
00520
00521 double brightFactor2 = (brightFactor / 65536.0 / NumSamples) *
00522 sqrt(outHeight * outWidth / (320.0 * 200.0));
00523
00524 energy_avg = energy_avg * 0.95 + energy * 0.05;
00525 if (energy_avg > 0.0)
00526 brightFactor2 *= 80.0 / (energy_avg + 5.0);
00527
00528 for(i = 1; i < NumSamples / 2; i++)
00529 {
00530 if (a[i] > 0 || b[i] > 0)
00531 {
00532 int h = (int)(b[i] * outWidth / (a[i] + b[i]));
00533 int br1, br2, br = (int)((a[i] + b[i]) * i * brightFactor2);
00534 br1 = br * (clarity[i] + 128) >> 8;
00535 br2 = br * (128 - clarity[i]) >> 8;
00536 if (br1 < 0) br1 = 0; else if (br1 > 255) br1 = 255;
00537 if (br2 < 0) br2 = 0; else if (br2 > 255) br2 = 255;
00538
00539 int px = h,
00540 py = outHeight - i * outHeight / (NumSamples / 2);
00541
00542 if (pointsAreDiamonds)
00543 {
00544 addPixel(px, py, br1, br2);
00545 br1 = scaleDown[br1];
00546 br2 = scaleDown[br2];
00547
00548 for(j = 1; br1 > 0 || br2 > 0;
00549 j++, br1 = scaleDown[br1], br2 = scaleDown[br2])
00550 {
00551 for (k = 0; k < j; k++)
00552 {
00553 addPixel(px - j + k,py - k, br1, br2);
00554 addPixel(px + k, py - j + k, br1, br2);
00555 addPixel(px + j - k, py + k, br1, br2);
00556 addPixel(px - k, py + j - k, br1, br2);
00557 }
00558 }
00559 }
00560 else
00561 {
00562 if (px < maxStarRadius || py < maxStarRadius ||
00563 px > outWidth - maxStarRadius ||
00564 py > outHeight - maxStarRadius)
00565 {
00566 addPixel(px, py, br1, br2);
00567 for( j = 1; br1 > 0 || br2 > 0;
00568 j++, br1 = scaleDown[br1], br2 = scaleDown[br2])
00569 {
00570 addPixel(px + j, py, br1, br2);
00571 addPixel(px, py + j, br1, br2);
00572 addPixel(px - j, py, br1, br2);
00573 addPixel(px, py - j, br1, br2);
00574 }
00575 }
00576 else
00577 {
00578 unsigned char *p = output + px * 2 + py * outWidth * 2,
00579 *p1=p, *p2=p, *p3=p, *p4=p;
00580 addPixelFast(p, br1, br2);
00581 for (; br1 > 0 || br2 > 0;
00582 br1 = scaleDown[br1], br2=scaleDown[br2])
00583 {
00584 p1 += 2;
00585 addPixelFast(p1, br1, br2);
00586 p2 -= 2;
00587 addPixelFast(p2, br1, br2);
00588 p3 += outWidth * 2;
00589 addPixelFast(p3, br1, br2);
00590 p4 -= outWidth*2;
00591 addPixelFast(p4, br1, br2);
00592 }
00593 }
00594 }
00595 }
00596 }
00597
00598 return false;
00599 }
00600
00601 bool Synaesthesia::draw(QPainter *p, const QColor &back)
00602 {
00603 (void)p;
00604 (void)back;
00605 #ifdef SDL_SUPPORT
00606 if (!surface)
00607 {
00608 cerr << "No sdl surface\n";
00609 return false;
00610 }
00611
00612 SDL_LockSurface(surface);
00613
00614 register uint32_t *ptrOutput = (uint32_t *)output;
00615
00616 for (int j = 0; j < outHeight * 2; j += 2)
00617 {
00618 uint32_t *ptrTop = (uint32_t *)(surface->pixels) + outWidth / 4 * j;
00619 uint32_t *ptrBot = (uint32_t *)(surface->pixels) +
00620 outWidth / 4 * (j + 1);
00621
00622 int i = outWidth / 4;
00623
00624 do {
00625 register unsigned int const r1 = *(ptrOutput++);
00626 register unsigned int const r2 = *(ptrOutput++);
00627 register unsigned int const v = ((r1 & 0x000000f0ul) >> 4) |
00628 ((r1 & 0x0000f000ul) >> 8) |
00629 ((r1 & 0x00f00000ul) >> 12) |
00630 ((r1 & 0xf0000000ul) >> 16);
00631 *(ptrTop++) = v | ( ((r2 & 0x000000f0ul) << 12) |
00632 ((r2 & 0x0000f000ul) << 8 ) |
00633 ((r2 & 0x00f00000ul) << 4 ) |
00634 ((r2 & 0xf0000000ul)));
00635
00636 *(ptrBot++) = v | ( ((r2 & 0x000000f0ul) << 12) |
00637 ((r2 & 0x0000f000ul) << 8 ) |
00638 ((r2 & 0x00f00000ul) << 4 ) |
00639 ((r2 & 0xf0000000ul)));
00640 }while(--i);
00641 }
00642
00643 SDL_UnlockSurface(surface);
00644 SDL_Flip(surface);
00645
00646 return false;
00647 #else
00648
00649 if (!outputImage)
00650 return false;
00651
00652 register uint32_t *ptrOutput = (uint32_t *)output;
00653
00654 for (int j = 0; j < outHeight * 2; j += 2)
00655 {
00656 uint32_t *ptrTop = (uint32_t *)(outputImage->scanLine(j));
00657 uint32_t *ptrBot = (uint32_t *)(outputImage->scanLine(j+1));
00658
00659 int i = outWidth / 4;
00660
00661 do
00662 {
00663 register unsigned int const r1 = *(ptrOutput++);
00664 register unsigned int const r2 = *(ptrOutput++);
00665
00666 register unsigned int const v = ((r1 & 0x000000f0ul) >> 4) |
00667 ((r1 & 0x0000f000ul) >> 8) |
00668 ((r1 & 0x00f00000ul) >> 12) |
00669 ((r1 & 0xf0000000ul) >> 16);
00670
00671 *(ptrTop++) = v | (((r2 & 0x000000f0ul) << 12) |
00672 ((r2 & 0x0000f000ul) << 8) |
00673 ((r2 & 0x00f00000ul) << 4) |
00674 ((r2 & 0xf0000000ul)));
00675
00676 *(ptrBot++) = v | (((r2 & 0x000000f0ul) << 12) |
00677 ((r2 & 0x0000f000ul) << 8) |
00678 ((r2 & 0x00f00000ul) << 4) |
00679 ((r2 & 0xf0000000ul)));
00680 } while (--i);
00681 }
00682
00683 p->drawImage(QRect(0, 0, 800, 600), *outputImage);
00684
00685 return true;
00686 #endif
00687 }
00688
00689 static class SynaesthesiaFactory : public VisFactory
00690 {
00691 public:
00692 const QString &name(void) const
00693 {
00694 static QString name("Synaesthesia");
00695 return name;
00696 }
00697
00698 uint plugins(QStringList *list) const
00699 {
00700 *list << name();
00701 return 1;
00702 }
00703
00704 VisualBase *create(MainVisual *parent, long int winid, const QString &pluginName) const
00705 {
00706 (void)parent;
00707 (void)pluginName;
00708 return new Synaesthesia(winid);
00709 }
00710 } SynaesthesiaFactory;