Bug 52008 - synaescope and tippercanoe don't work with Sparc Solaris - endian problem
Summary: synaescope and tippercanoe don't work with Sparc Solaris - endian problem
Status: RESOLVED INTENTIONAL
Alias: None
Product: noatun
Classification: Miscellaneous
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources Solaris
: NOR normal
Target Milestone: ---
Assignee: Multimedia Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-12-17 08:31 UTC by Aaron Williams
Modified: 2008-08-01 13:42 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Patch for tippercanoe (3.24 KB, patch)
2003-08-14 00:01 UTC, Aaron Williams
Details
My patches to tyler for Solaris (8.21 KB, patch)
2003-08-14 00:02 UTC, Aaron Williams
Details
Patches to Synaescope (4.95 KB, patch)
2003-08-14 00:03 UTC, Aaron Williams
Details
patch for kdeaddons/noatun-plugins/synaescope (1.47 KB, patch)
2003-12-20 23:17 UTC, Torsten Kasch
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Aaron Williams 2002-12-17 08:31:09 UTC
Version:            (using KDE KDE 3.0.99)
Installed from:    Compiled From Sources
Compiler:          gcc 2.95.3 Ultrasparc, Solaris 2.7
OS:          Solaris

Both synaescope and tippercanoe have problems on big-endian platforms since
the data is little endian.  Also, on Solaris it doesn't seem to detect that the system
is big endian.  The following patches seem to fix the problems in both programs:

in syna.h:

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_ENDIAN_H
#include <endian.h>
+ #elif defined(_BIG_ENDIAN)
+ #define BIG_ENDIAN 1
+ #define BYTE_ORDER BIG_ENDIAN
#endif
typedef short sampleType;
#endif


in core.cpp:

bool Core::calculate()
{
	double x[NumSamples], y[NumSamples];
	double a[NumSamples], b[NumSamples];
	int clarity[NumSamples]; //Surround sound
	int i,j,k;
+ #ifndef LITTLE_ENDIAN
+         register sampleType temp;
+ #endif
	int brightFactor = int(Brightness * brightnessTwiddler /(starSize+0.01));

...

	for(i=0;i<NumSamples;i++)
	{
+ #ifdef LITTLEENDIAN
		x[i] = data[i*2];
		y[i] = data[i*2+1];
+ #else
+                //  Need to convert to big-endian
+                temp = data[i*2];
+                temp = (temp >> 8) | (temp << 8);
+                x[i] = temp;
+                temp = data[i*2+1];
+                temp = (temp << 8) | (temp >> 8);
+                y[i] = temp;
+#endif
	}


Another problem I see is that the plugins should be run as low priority, especially on slow systems.

The following patch to main.cpp fixes this problem:

in main.cpp:

#include <fcntl.h>
+ #include <sys/resource.h>

...

int main()
{
	fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) & ~O_NONBLOCK);
	KInstance in("noatunsynaescope");
+        setpriority(PRIO_PROCESS, getpid(), 17);
	core=new Core;
Comment 1 Aaron Williams 2003-01-15 02:33:53 UTC
tyler also has problems.  I have patched it so that it works under Sparc Solaris, but it needs a little 
more cleanup before I submit the patches.  In addition, the code should be a little more effecient 
and should run at any color depth (even 8-bit in theory). 
 
The big problem with tyler is it requires reading a binary configuration file which is in little-endian 
format. 
Comment 2 Aaron Williams 2003-06-25 09:47:00 UTC
Here are some patches for the tyler plugin: 
 
--- display.c   2001-07-31 10:47:49.000000000 -0700 
+++ new/display.c       2003-01-14 02:14:46.000000000 -0800 
@@ -25,12 +25,11 @@ 
 
 #define wrap(a) ( a < 0 ? 0 : ( a > 255 ? 255 : a )) 
 #define assign_max(p,a) ( *p = ( *p > a ? *p : a )) 
-#define PI 3.14159 
- 
+#define PI 3.1415926535 
 #define VIDEO_FLAGS (SDL_SWSURFACE) 
 
 SDL_Color color_table[NB_PALETTES][256]; 
-short current_colors[256]; 
+Uint32 current_colors[256]; 
 
 byte* surface1; 
 byte* surface2; 
@@ -38,17 +37,17 @@ 
 void generate_colors() 
 { 
        int i,k; 
-       float colors[NB_PALETTES][2][3]={{{1,1,1},{1,1,1}}, 
-                                        {{2,1.5,0},{0,0.5,2}}, 
-                                        {{0,1,2},{0,1,0}}, 
-                                        {{0,2,1},{0,0,1}}, 
-                                        {{2,0,0},{0,1,1}}}; 
+       static const float colors[NB_PALETTES][2][3]={{{1.,1.,1.},{1.,1.,1.}}, 
+                                                      {{2.,1.5,0.},{0.,0.5,2.}}, 
+                                                      {{0.,1.,2.},{0.,1.,0.}}, 
+                                                      {{0.,2.,1.},{0.,0.,1.}}, 
+                                                      {{2.,0.,0.},{0.,1.,1.}}}; 
        for (k=0;k<NB_PALETTES;k++) { 
                for ( i=0; i<128; i++ ) 
                        { 
-                               color_table[k][i].r = colors[k][0][0]*i; 
-                               color_table[k][i].g = colors[k][0][1]*i; 
-                               color_table[k][i].b = colors[k][0][2]*i; 
+                               color_table[k][i].r = (int)(colors[k][0][0]*i); 
+                               color_table[k][i].g = (int)(colors[k][0][1]*i); 
+                               color_table[k][i].b = (int)(colors[k][0][2]*i); 
                        } 
                for ( i=0; i<128; i++ ) 
                        { 
@@ -62,14 +61,32 @@ 
 void change_color(int t2,int t1,int w) 
 { 
        int i; 
+        SDL_Color sdlPalette[256]; 
 
        for (i=0;i<255;i++) { 
                int r,g,b; 
+ 
+#if 0 
                r=color_table[t1][i].r*w+color_table[t2][i].r*(256-w)>>11; 
                g=color_table[t1][i].g*w+color_table[t2][i].g*(256-w)>>10; 
                b=color_table[t1][i].b*w+color_table[t2][i].b*(256-w)>>11; 
                current_colors[i]=(r<<11)+(g<<5)+b; 
+#else 
+                r = color_table[t1][i].r*w + color_table[t2][i].r*(256-w) >> 8; 
+                if (r > 255) 
+                    r = 255; 
+                g = color_table[t1][i].g*w + color_table[t2][i].g*(256-w) >> 8; 
+                if (g > 255) 
+                    g = 255; 
+                b = color_table[t1][i].b*w + color_table[t2][i].b*(256-w) >> 8; 
+                if (b > 255) 
+                    b = 255; 
+                sdlPalette[i].r = r; 
+                sdlPalette[i].g = g; 
+                sdlPalette[i].b = b; 
+#endif 
        } 
+        SDL_SetColors(screen, sdlPalette, 0, 256); 
 } 
 
 void compute_surface(t_interpol* vector_field) 
@@ -93,7 +110,7 @@ 
 
                        if (color>255) 
                                surface2[add_dest]=255; 
-                       else 
+                        else 
                                surface2[add_dest]=color; 
                        add_dest++; 
                } 
@@ -109,16 +126,24 @@ 
 void display_surface() 
 { 
        int i,j; 
- 
+        static unsigned char count = 0; 
+ 
+       if (SDL_MUSTLOCK(screen)) { 
+            if (SDL_LockSurface(screen) < 0) { 
+                fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 
+                return; 
+            } 
+        } 
        if (scr_par.scale>1) 
                for (i=0;i<scr_par.height;i++) { 
-                   short* pdest=(short*)(screen->pixels+i*screen->pitch*scr_par.scale); 
+                   Uint8* pdest=(Uint8*)(screen->pixels+i*screen->pitch*scr_par.scale); 
                    byte* psrc=surface1+i*scr_par.width; 
                    if (scr_par.scale==2) 
                    { 
                        for (j=1;j<scr_par.width;j++) { 
-                           *(pdest++)=current_colors[*psrc++]; 
-                           *(pdest++)=*(pdest-1); 
+                            /*  *(pdest++)=current_colors[*psrc++]; */ 
+                            *(pdest++) = *psrc; 
+                           *(pdest++) = *psrc++; 
                        } 
 
                        memcpy(screen->pixels+i*screen->pitch*2+screen->pitch, 
@@ -142,12 +167,17 @@ 
        else { 
            byte* psrc=surface1; 
            for (i=0;i<scr_par.height;i++) { 
-               short* pdest=(short*)(screen->pixels+i*screen->pitch); 
+               Uint8* pdest=(Uint8*)(screen->pixels+i*screen->pitch); 
                for (j=0;j<scr_par.width;j++) 
-                   *pdest++=current_colors[*psrc++]; 
+                    /*             *pdest++=current_colors[*psrc++] | 0x00001080U | count << 16;*/ 
+                    *pdest++ = *psrc++; 
            } 
        } 
+        if (SDL_MUSTLOCK(screen)) { 
+            SDL_UnlockSurface(screen); 
+        } 
        SDL_UpdateRect(screen, 0, 0, 0, 0); 
+        count++; 
 } 
 
 void blur(t_interpol* vector_field) 
@@ -425,15 +455,21 @@ 
                        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); 
                        exit(1); 
                } 
+ 
+        SDL_WM_SetCaption("Tyler","tyler"); 
 
-       screen = SDL_SetVideoMode(scr_par.width*scr_par.scale, 
scr_par.height*scr_par.scale, 
-                                 16,VIDEO_FLAGS); 
+       screen = SDL_SetVideoMode(scr_par.width*scr_par.scale, 
+                                  scr_par.height*scr_par.scale, 
+                                 8, VIDEO_FLAGS); 
        if ( screen == NULL ) 
                { 
                        fprintf(stderr, "Couldn't init video mode: %s\n", SDL_GetError()); 
                        exit(1); 
                } 
-       SDL_ShowCursor(0); 
+        /*     SDL_ShowCursor(0);*/ 
+        if (screen->format->BytesPerPixel != 1) { 
+            exit(1); 
+        } 
        SDL_EnableKeyRepeat(0,0); 
 
 } 
 
 
 
 
--- file.cpp    2002-05-18 04:51:46.000000000 -0700 
+++ new/file.cpp        2003-01-14 02:11:33.000000000 -0800 
@@ -39,19 +39,44 @@ 
        return dirs.saveLocation("data", "noatun/") + "tylerstates"; 
 } 
 
+static Uint32 readWord(QFile &file) 
+{ 
+    Uint32 word; 
+    word = file.getch() | 
+            (file.getch() << 8) | 
+            (file.getch() << 16) | 
+            (file.getch() << 24); 
+    return word; 
+} 
+ 
+static void writeWord(QFile &file, Uint32 word) 
+{ 
+    file.putch(word & 255); 
+    file.putch((word>>8) & 255); 
+    file.putch((word >> 16) & 255); 
+    file.putch(word >> 24); 
+} 
+ 
 extern "C" void save_effect(t_effect *effect) 
 { 
        QFile file(getSavePath()); 
        if(!file.open(IO_WriteOnly)) 
                return; 
 
-       for(unsigned i = 0; i < sizeof(t_effect); i++) 
-               file.putch( *((byte *)effect + i) ); 
+        writeWord(file, effect->num_effect); 
+        writeWord(file, effect->x_curve); 
+        writeWord(file, effect->curve_color); 
+        writeWord(file, effect->curve_amplitude); 
+        writeWord(file, effect->spectral_amplitude); 
+        writeWord(file, effect->spectral_color); 
+        writeWord(file, effect->mode_spectre); 
+        writeWord(file, effect->spectral_shift); 
 } 
 
 t_effect effects[100]; 
 int nb_effects=0; 
 
+ 
 extern "C" void load_effects() 
 { 
        QFile file(getDataPath()); 
@@ -59,11 +84,17 @@ 
                exit(1); 
 
        nb_effects = 0; 
-       while(!file.atEnd()) 
+       while(!file.atEnd() && nb_effects < 100) 
        { 
-               byte* ptr_effect = (byte *)&effects[nb_effects++]; 
-               for(int i = 0; i < sizeof(t_effect); i++) 
-                       ptr_effect[i] = file.getch(); 
+               t_effect* ptr_effect = &effects[nb_effects++]; 
+                ptr_effect->num_effect = readWord(file); 
+                ptr_effect->x_curve = readWord(file); 
+                ptr_effect->curve_color = readWord(file); 
+                ptr_effect->curve_amplitude = readWord(file); 
+                ptr_effect->spectral_amplitude = readWord(file); 
+                ptr_effect->spectral_color = readWord(file); 
+                ptr_effect->mode_spectre = readWord(file); 
+                ptr_effect->spectral_shift = readWord(file); 
        } 
 } 
 
 
 
 
--- main.cpp    2002-01-02 05:19:49.000000000 -0800 
+++ new/main.cpp        2003-01-14 01:04:22.000000000 -0800 
@@ -29,6 +29,7 @@ 
 #include <unistd.h> 
 #include <sys/time.h> 
 #include <sys/types.h> 
+#include <sys/resource.h> 
 
 #include "renderer.h" 
 #include "display.h" 
@@ -65,10 +66,11 @@ 
 { 
        fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) & 
~O_NONBLOCK); 
 
-       atexit(SDL_Quit); 
- 
        KInstance in("noatuntyler"); 
 
+        setpriority(PRIO_PROCESS, getpid(), 18); 
+       atexit(SDL_Quit); 
+ 
        finished = false; 
        access_mutex = SDL_CreateMutex(); 
 
@@ -90,6 +92,15 @@ 
                { 
                        SDL_mutexP(access_mutex); 
                        read(STDIN_FILENO, (void *)pcm_data, sizeof(short) * 2 * 512); 
+                        for (int i=0; i<512; i++) { 
+                            register short temp; 
+                            temp = pcm_data[0][i]; 
+                            temp = (temp >> 8) | (temp << 8); 
+                            pcm_data[0][i] = temp; 
+                            temp = pcm_data[1][i]; 
+                            temp = (temp >> 8) | (temp << 8); 
+                            pcm_data[1][i] = temp; 
+                        } 
                        SDL_mutexV(access_mutex); 
                } 
        } 
 
Comment 3 Charles Samuels 2003-08-11 06:47:25 UTC
Subject: kdeaddons/noatun-plugins/tippercanoe

CVS commit by charles: 

fix endian according to 52008
(synaescope was fixed too)
CCMAIL:52008@bugs.kde.org


  M +14 -1     core.cpp   1.3
  M +3 -0      syna.h   1.7


--- kdeaddons/noatun-plugins/tippercanoe/core.cpp  #1.2:1.3
@@ -300,4 +300,7 @@ bool Core::calculate()
         int clarity[NumSamples]; //Surround sound
         int i,j,k;
+#ifndef LITTLE_ENDIAN 
+        register sampleType temp; 
+#endif 
 
         int brightFactor = int(Brightness * brightnessTwiddler /(starSize+0.01));  
@@ -309,6 +312,16 @@ bool Core::calculate()
         for(i=0;i<NumSamples;i++)
         {
+#       ifdef LITTLEENDIAN 
                 x[i] = data[i*2];
                 y[i] = data[i*2+1];
+#       else 
+                // Need to convert to big-endian 
+                temp = data[i*2]; 
+                temp = (temp >> 8) | (temp << 8); 
+                x[i] = temp; 
+                temp = data[i*2+1]; 
+                temp = (temp << 8) | (temp >> 8); 
+                y[i] = temp; 
+#       endif 
         }
 

--- kdeaddons/noatun-plugins/tippercanoe/syna.h  #1.6:1.7
@@ -61,4 +61,7 @@ typedef unsigned short sampleType;
 #ifdef HAVE_ENDIAN_H
 #include <endian.h>
+#elif defined(_BIG_ENDIAN) 
+#define BIG_ENDIAN 1
+#define BYTE_ORDER BIG_ENDIAN
 #endif
 typedef short sampleType;


Comment 4 Charles Samuels 2003-08-11 06:49:00 UTC
please submit the tyler patch again as an attachment so I can apply it without a billion 
very long rejects. 
 
-Charles 
 
Comment 5 Aaron Williams 2003-08-14 00:01:09 UTC
Created attachment 2234 [details]
Patch for tippercanoe

My patches to Tippercanoe to make it work properly on Sparc Solaris
Comment 6 Aaron Williams 2003-08-14 00:02:24 UTC
Created attachment 2235 [details]
My patches to tyler for Solaris

This is a diff between my patched tyler from KDE 3.1.2 and the KDE 3.1.3
release.
Comment 7 Aaron Williams 2003-08-14 00:03:17 UTC
Created attachment 2236 [details]
Patches to Synaescope

Here is a diff between my patched 3.1.2 synaescope and the default 3.1.3 files.
Comment 8 Aaron Williams 2003-08-14 00:54:04 UTC
Included in the diffs are some performance enhancements I made.  Unsigned numbers 
can be faster than ints on some architectures and generally are never slower.  Also I 
simplified some of the calculations in the fft code a little bit. 
 
I might add that my patch for main.cpp in tyler needs an #ifdef for BIGENDIAN.  Also, my 
other changes in tyler eliminate the requirement that X run in 16bpp.  It uses SDL to do 
the palette conversion instead. 
 
These patches have been tested on Solaris and HAVE NOT been tested in Linux or on a 
little-endian machine.  All of the patches should work with the exception being main.cpp 
in tyler as stated above. 
 
-Aaron 
Comment 9 Charles Samuels 2003-08-24 16:42:53 UTC
This (tyler) patch doesn't work on my i386, even with a #ifdef BIGENDIAn around the for 
in main.cpp. 
 
The rest have already been applied. 
Comment 10 Eray Ozkural 2003-10-21 14:38:23 UTC
what's the status of this bug now?
Comment 11 Aaron Williams 2003-10-21 21:33:18 UTC
Subject: Re:  synaescope and tippercanoe don't work with Sparc
 Solaris - endian problem

There are still problems.  One problem is the endianess, in that all the 
samples are in little endian format.  Synascope doesn't seem to work at 
all in 3.1.4 on Solaris 2.8.

I can try and track down the problems when I have a bit of time.

-Aaron

Comment 12 Torsten Kasch 2003-12-20 23:07:39 UTC
Somewhat related to this bug (2 independent problems, in fact): Trying to compile kdeaddons HEAD on my Solaris 8 x86 box (little endian) with gcc 2.95.3 fails with:

source='synaescope.cpp' object='synaescope.lo' libtool=yes \
depfile='.deps/synaescope.Plo' tmpdepfile='.deps/synaescope.TPlo' \
depmode=gcc /bin/ksh ../../admin/depcomp \
/bin/ksh ../../libtool --silent --mode=compile --tag=CXX g++ -DHAVE_CONFIG_H -I. -I. -I../.. -I/vol/kde-cvs/include -I/vol/qt-3.2.3/include   -I/vol/local/include -I/vol/graphics/include -I/vol/local/include/SDL -D_REENTRANT  -DQT_THREAD_SUPPORT -I/vol/openssl/include -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_SOLARIS -DSVR4  -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -W -Wpointer-arith -Wwrite-strings -DNDEBUG -DNO_DEBUG -O2 -fno-exceptions -fno-check-new -fno-common -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION  -c -o synaescope.lo `test -f 'synaescope.cpp' || echo './'`synaescope.cpp
In file included from synaescope.h:11,
                 from synaescope.cpp:8:
syna.h:52: warning: #warning This target has not been tested!
syna.h:59: warning: #warning using sys/types.h
In file included from synaescope.h:11,
                 from synaescope.cpp:8:
syna.h:74: warning: `LITTLE_ENDIAN' is not defined
syna.h:74: warning: `BIG_ENDIAN' is not defined
synaescope.cpp: In method `void SynaeScope::receivedStdout(KProcess *, char *, int)':
synaescope.cpp:100: declaration of `__iob' as array of references
synaescope.cpp:100: invalid declarator
synaescope.cpp: In method `void SynaeScope::receivedStderr(KProcess *, char *, int)':
synaescope.cpp:106: declaration of `__iob' as array of references
synaescope.cpp:106: invalid declarator
make: *** [synaescope.lo] Error 1

Problem 1: "little endianess" isn't detected correctly
Problem 2: the naming of 2 QCStrings as "stdout" and "stderr" (line 100 and 106, respectively)
Comment 13 Torsten Kasch 2003-12-20 23:17:08 UTC
Created attachment 3803 [details]
patch for kdeaddons/noatun-plugins/synaescope

I'm not sure if this is the most elegant way to fix these issues, but at least
the plugin compiles and seems to work ok on my laptop.
Comment 14 Stefan Gehn 2004-10-20 22:47:17 UTC
is the last patch ok for everybody now? If yes then I'd be happy to commit this.
Comment 15 Stefan Gehn 2005-02-09 19:32:41 UTC
Uhm, no comments anymore? Is it fixed?
Comment 16 George Goldberg 2007-12-19 04:03:37 UTC
Is this bug still there in a recent version of KDE, such as 3.5.8 or KDE4.0 RC2?
Comment 17 Aaron Williams 2007-12-20 00:17:03 UTC
I've kept running in to it even in recent versions. The problem is that the data files are saved in little endian format, so they don't work on big endian machines.

For it to be truly fixed, the data files should be saved in a specific format (little or big) and the code should only support that format.

I don't know about 3.5.8, but I know earlier 3.5 releases had the problem.

I am no longer running Solaris (thank god) so I cannot test this.
Comment 18 groot 2008-08-01 13:42:49 UTC
noatun is out of scope for KDE4 on SPARC Solaris. Older versions may be considered unsupported.