Get these same errors on different machines with variations on this code which leads me to believe there is something very basic that's wrong with our code!!
ERROR / OUTPUT :
Serial Ports List: /dev/cu.Bluetooth-Incoming-Port /dev/cu.usbmodem1508001 /dev/tty.Bluetooth-Incoming-Port /dev/tty.usbmodem1508001 port 0: 0 2016-08-29 19:25:26.801 java[7376:1888340] 19:25:26.801 WARNING: 140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h. error, disabling movieEvent() for /Volumes/Untitled/Users/Dirkblaze/Movies/Semaphore.avi java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.fireMovieEvent(Unknown Source) at processing.video.Movie.invokeEvent(Unknown Source) at processing.video.Movie$2.rgbFrame(Unknown Source) at org.gstreamer.elements.RGBDataAppSink$AppSinkNewBufferListener.newBuffer(RGBDataAppSink.java:162) at org.gstreamer.elements.AppSink$2.callback(AppSink.java:184) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:485) at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:515) Caused by: java.lang.ArrayIndexOutOfBoundsException: 2400 at movie2serial.image2data(movie2serial.java:186) at movie2serial.movieEvent(movie2serial.java:129) ... 15 more
CODE:
import processing.video.*; import processing.serial.*; import java.awt.Rectangle;
Movie myMovie;
final int SCREEN_WIDTH = 50; final int SCREEN_HEIGHT = 16;
final int PANEL_WIDTH=100; final int PANEL_HEIGHT=100; final int PANELS_PER_PIN = 1; final int LEDS_PER_STRIP = PANEL_WIDTH * PANEL_HEIGHT * PANELS_PER_PIN;
float gamma = 1.7;
int numPorts=0; // the number of serial ports in use int maxPorts=24; // maximum number of serial ports
Serial[] ledSerial = new Serial[maxPorts]; // each port's actual Serial port Rectangle[] ledArea = new Rectangle[maxPorts]; // the area of the movie each port gets, in % (0-100) boolean[] ledLayout = new boolean[maxPorts]; // layout of rows, true = even is left->right PImage[] ledImage = new PImage[maxPorts]; // image sent to each port int[] gammatable = new int[256]; int errorCount=0; int errorNumber=0; int i=0; float framerate=0;
void setup() { String[] list = Serial.list();
myMovie = new Movie(this, "/Volumes/Untitled/Users/Dirkblaze/Movies/Semaphore.avi");
delay(2); println("Serial Ports List:"); println(list);
serialConfigure("/dev/tty.usbmodem1508001");
if (errorCount > 0) exit(); for (int i=0; i < 1; i++) { /// ********** 255 changed to 1 for testing; error happens regardless! println(i);
// ********** Error takes place shortly after executing this line:
gammatable[i] = (int)(pow((float)i / 255.0, gamma) * 255.0 + 0.5);
}
size(1024,768); // create the window myMovie.loop(); // start the movie :-) }
// movieEvent runs for each new frame of movie data void movieEvent(Movie m) { // read the movie's next frame m.read();
//if (framerate == 0) framerate = m.getSourceFrameRate(); framerate = 30.0; // TODO, how to read the frame rate???
for (int i=0; i < numPorts; i++) {
// copy a portion of the movie's image to the LED image
int xoffset = percentage(m.width, ledArea[i].x);
int yoffset = percentage(m.height, ledArea[i].y);
int xwidth = percentage(m.width, ledArea[i].width);
int yheight = percentage(m.height, ledArea[i].height);
ledImage[i].copy(m, xoffset, yoffset, xwidth, yheight,
0, 0, ledImage[i].width, ledImage[i].height);
// convert the LED image to raw data
byte[] ledData = new byte[(ledImage[i].width * ledImage[i].height * 3) + 3];
image2data(ledImage[i], ledData, ledLayout[i]);/*
if (i == 0) {
ledData[0] = ''; // first Teensy is the frame sync master
int usec = (int)((1000000.0 / framerate) * 0.75);
ledData[1] = (byte)(usec); // request the frame sync pulse
ledData[2] = (byte)(usec >> 8); // at 75% of the frame time
} else {
ledData[0] = '%'; // others sync to the master board
ledData[1] = 0;
ledData[2] = 0;
}/
// send the raw data to the LEDs :-)
ledSerial[i].write(ledData);
}
}
int led_map(int input) { int row = input / LEDS_PER_STRIP; input %= LEDS_PER_STRIP;
int y = input / ( SCREEN_WIDTH ); int x = input % ( SCREEN_WIDTH );
if((x%2)==1) { y = 7-y; }
int output = row * LEDS_PER_STRIP + x * PANEL_HEIGHT + y; return output; }
int led_map(int x,int y) { return led_map(y * SCREEN_WIDTH + x); }
// image2data converts an image to OctoWS2811's raw data format. // The number of vertical pixels in the image must be a multiple // of 8. The data array must be the proper size for the image. void image2data(PImage image, byte[] data, boolean layout) { int offset = 0; int x, y, mask; int pixel; int i=0;
for (y = 0; y < image.height; y++) { for (x = 0; x < image.width; x++) { pixel = image.pixels[i++]; int r = ( pixel ) >> 16; int g = ( pixel ) >> 8; int b = ( pixel ); offset = led_map(x,y)*3; data[offset++] = (byte)(r & 0xfe); data[offset++] = (byte)(g & 0xfe); data[offset++] = (byte)(b & 0xfe); } } offset=0; data[offset++] |= (byte)0x01; data[offset++] |= (byte)0x01; data[offset++] |= (byte)0x01; }
// translate the 24 bit color from RGB to the actual // order used by the LED wiring. GRB is the most common. int colorWiring(int c) { int red = (c & 0xFF0000) >> 16; int green = (c & 0x00FF00) >> 8; int blue = (c & 0x0000FF); red = gammatable[red]; green = gammatable[green]; blue = gammatable[blue]; return (green << 16) | (red << 8) | (blue); // GRB - most common wiring }
// ask a Teensy board for its LED configuration, and set up the info for it. void serialConfigure(String portName) { if (numPorts >= maxPorts) { println("too many serial ports, please increase maxPorts"); errorCount++; return; } try { ledSerial[numPorts] = new Serial(this, portName); if (ledSerial[numPorts] == null) throw new NullPointerException(); ledSerial[numPorts].write('?'); } catch (Throwable e) { println("Serial port " + portName + " does not exist or is non-functional"); errorCount++; return; } delay(50);/* String line = ledSerial[numPorts].readStringUntil(10); if (line == null) { println("Serial port " + portName + " is not responding."); println("Is it really a Teensy 3.0 running VideoDisplay?"); errorCount++; return; } */ print("port "+numPorts+": "); String line = "32,24,0,0,0,0,0,100,100,0,0,0"; String param[] = line.split(","); if (param.length != 12) { println("Error: port " + portName + " did not respond to LED config query"); errorCount++; return; } // only store the info and increase numPorts if Teensy responds properly ledImage[numPorts] = new PImage(Integer.parseInt(param[0]), Integer.parseInt(param[1]), RGB); ledArea[numPorts] = new Rectangle(Integer.parseInt(param[5]), Integer.parseInt(param[6]), Integer.parseInt(param[7]), Integer.parseInt(param[8])); ledLayout[numPorts] = (Integer.parseInt(param[5]) == 0); numPorts++; }
// draw runs every time the screen is redrawn - show the movie... void draw() { // show the original video image(myMovie, 0, 80);
// then try to show what was most recently sent to the LEDs // by displaying all the images for each port. for (int i=0; i < numPorts; i++) { // compute the intended size of the entire LED array int xsize = percentageInverse(ledImage[i].width, ledArea[i].width); int ysize = percentageInverse(ledImage[i].height, ledArea[i].height); // computer this image's position within it int xloc = percentage(xsize, ledArea[i].x); int yloc = percentage(ysize, ledArea[i].y); // show what should appear on the LEDs image(ledImage[i], 240 - xsize / 2 + xloc, 10 + yloc); } }
// respond to mouse clicks as pause/play boolean isPlaying = true; void mousePressed() { if (isPlaying) { myMovie.pause(); isPlaying = false; } else { myMovie.play(); isPlaying = true; } }
// scale a number by a percentage, from 0 to 100 int percentage(int num, int percent) { double mult = percentageFloat(percent); double output = num * mult; return (int)output; }
// scale a number by the inverse of a percentage, from 0 to 100 int percentageInverse(int num, int percent) { double div = percentageFloat(percent); double output = num / div; return (int)output; }
// convert an integer from 0 to 100 to a float percentage // from 0.0 to 1.0. Special cases for 1/3, 1/6, 1/7, etc // are handled automatically to fix integer rounding. double percentageFloat(int percent) { if (percent == 33) return 1.0 / 3.0; if (percent == 17) return 1.0 / 6.0; if (percent == 14) return 1.0 / 7.0; if (percent == 13) return 1.0 / 8.0; if (percent == 11) return 1.0 / 9.0; if (percent == 9) return 1.0 / 11.0; if (percent == 8) return 1.0 / 12.0; return (double)percent / 100.0; }