Hammertime ! (video streaming with audio) with INSTRUCTIONS

Libraries, utilities, bootloaders...

Hammertime ! (video streaming with audio) with INSTRUCTIONS

Postby jonnection » Wed Mar 18, 2015 5:21 pm

Happy b-day to Gamebuino also from me, here's a little gift:



https://youtu.be/wH6YXncjpPs

- the sound quality is still quite bad ( 6552 Hz) but this was a proof of concept, I will make better versions. Framerate is 13 fps.
- I will get back to the question of how to make your own videos like this later, as it requires several tools (ffmpg, imagemagick and 2 custom programs I made)

How to play it yourself:

1) The HEX for the player is in the attachment below
THERE IS NO GAMEBUINO MENU IN THIS DEMO, YOU HAVE TO USE "c" BUTTON DURING BOOT TO LOAD ANOTHER HEX AFTER THIS !!!

2) You can download the "U Can't Touch This" video file over here. Put the "VIDEO.JVD" file in the root of the SD card.

https://drive.google.com/file/d/0BweEjvtKj1KLb2IwQkxqTG05ems/view?usp=sharing

3) Here is the source code to the actual player on the Gamebuino, if you want to upload it from the Arduino IDE:

Code: Select all
// Happy Birthday Gamebuino !
// Jonne Valola aka "Jonnection"
// Combines parts of Myndale's SD audio streaming demo
// and petit_fs lib demo

#include <TimerOne.h>
#include <petit_fatfs.h>

#define PLAYBACK_FREQ 6552 // was 6552
#define SPEAKER 3
#define BUFFER_SIZE 128

// GAMEBUINO DEFINED PINS
#define PIN_SCE   A1 // PC 1 SCR ENABLE
#define PIN_RESET A0 // PC 0 SCR RESET
#define PIN_DC    A2 // PC 2 SCR DC
#define PIN_SDIN  11 // PB 3 MOSI - data to screen
#define PIN_SCLK  13 // PB 5 SCK
#define PIN_BACKLIGHT 5 // PD 5 BACKLIGHT

#define PORT_SCLK PORTB
#define SCLK_BIT 5
#define PORT_SDIN PORTB
#define SDIN_BIT 3

#define LCD_C     LOW
#define LCD_D     HIGH
#define LCD_CMD   0

#define LCD_X     84
#define LCD_Y     48
byte buffer[LCD_X*LCD_Y/8];
unsigned char buffers[2][BUFFER_SIZE];
volatile int currentBuffer = 0;
volatile int bufindex = 0;
volatile boolean blit=false;
volatile unsigned char * currentPtr;
volatile unsigned char * endPtr;

const int chipSelect = 10;
WORD br;

void LcdClear(void)
{
  for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
  {
    LcdWrite(LCD_D, 0x00);
  }
}

void LcdInitialise(void)
{
  pinMode(PIN_SCE,   OUTPUT);
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DC,    OUTPUT);
  pinMode(PIN_SDIN,  OUTPUT);
  pinMode(PIN_SCLK,  OUTPUT);

  digitalWrite(PIN_RESET, LOW);
  digitalWrite(PIN_RESET, HIGH);

  LcdWrite( LCD_CMD, 0x21 );  // LCD Extended Commands.
  LcdWrite( LCD_CMD, 0xB9 );  // Set LCD Vop (Contrast). //B1
  LcdWrite( LCD_CMD, 0x04 );  // Set Temp coefficent. //0x04
  LcdWrite( LCD_CMD, 0x14 );  // LCD bias mode 1:48. //0x13
  LcdWrite( LCD_CMD, 0x0C );  // LCD in normal mode. 0x0d for inverse
  LcdWrite(LCD_C, 0x20);
  LcdWrite(LCD_C, 0x0C);

  pinMode(5, OUTPUT); //backlight
  digitalWrite(5, HIGH);
}

void LcdWrite(byte dc, byte data) {
  digitalWrite(PIN_DC, dc); // select command or data mode
  digitalWrite(PIN_SCE, LOW); // enable screen
  digitalWrite(SS, HIGH); // disable SD
  tx(data); // replace with hardware version from petit_fs demo
  digitalWrite(PIN_SCE, HIGH); // disable screen
}

void gotoXY(int x, int y) {
  LcdWrite( 0, 0x80 | x);  // Column.
  LcdWrite( 0, 0x40 | y);  // Row. 
}

void setup(void)
{
  spi_init();
  Serial.begin(9600);
  Serial.println(F("Starting videoplayer"));
 
  int a = PFFS.begin(10, rx, tx);
  Serial.println(F("SD begin succeeded"));
  int err = PFFS.open_file("VIDEO.JVD");
  if (err) Serial.println(F("Video open failed"));
  else Serial.println(F("Video open success"));
 
  if (err==0) {
      Serial.println(F("Data file opened"));
      pf_read((void *)&buffers[0][0],BUFFER_SIZE,&br);
      currentBuffer = 0;
      currentPtr = buffers[currentBuffer];
      endPtr = currentPtr + BUFFER_SIZE;
      pinMode(SPEAKER, OUTPUT);
      TCCR2B = (TCCR2B & 0b11111000) | 0x01;  // set max PWM frequency
      Timer1.initialize(1000000/PLAYBACK_FREQ);
      Timer1.attachInterrupt(callback); 
  }
  LcdInitialise();
  gotoXY(0,0);
  LcdClear();
}

void loop(void)
{
  digitalWrite(SS, LOW);
  pf_read((void *)&buffers[1][0],BUFFER_SIZE,&br);
  digitalWrite(SS, HIGH);
  while (currentBuffer != 1) if (blit) blitscreen();
  digitalWrite(SS, LOW);
  pf_read((void *)&buffers[0][0],BUFFER_SIZE,&br);
  digitalWrite(SS, HIGH);
  while (currentBuffer != 0) if (blit) blitscreen();
}

void callback()
{
  buffer[bufindex] = (*currentPtr++);
  bufindex++;
  if (bufindex == 504) {
    bufindex=0;
    blit=true;
  }
  analogWrite(SPEAKER, (*currentPtr++));
  if (currentPtr >= endPtr)
  {
    currentBuffer = 1-currentBuffer;
    currentPtr = buffers[currentBuffer];
    endPtr = currentPtr + BUFFER_SIZE;
  }
}

byte rx()
{
  // The SPI Data Register is a read/write register
  // used for data transfer between the Register File and the SPI Shift Register.
  // Writing to the register initiates data transmission. Reading the register causes the Shift Register receive buffer to be read.
  SPDR = 0xFF; // dummy byte to initiate reading
  // loop_until_bit_is_set is an AVR libc macro
  // SPSR is SPI status register, SPIF is SPI interrupt flag, that is set after transmission is complete
  loop_until_bit_is_set(SPSR, SPIF);
  return SPDR; //return the SPDR (= value back from slave)
}

void tx(byte d)
{
  SPDR = d;
  loop_until_bit_is_set(SPSR, SPIF);
}

void spi_init()
{
  pinMode(10, OUTPUT); // 10 = SS = Slave select of SD
  pinMode(11, OUTPUT); // MOSI data to SD
  pinMode(12, INPUT);  // PB 4 - MISO data from SD
  pinMode(13, OUTPUT); // SCLK
 
  // SET HARDWARE SPI in Master & enabled
  // default speed is Clock/4 = 4 Mhz which is maximum for nokia lcd
  SPCR = _BV(MSTR) | _BV(SPE);      // Master mode, SPI enable, clock speed MCU_XTAL/4
}

inline void blitscreen()
{
  digitalWrite(PIN_DC, HIGH); // select data mode
  digitalWrite(PIN_SCE, LOW); // enable screen
  digitalWrite(SS, HIGH); // disable SD
  for (int i = 0; i < 504; i++)
  {
     tx(buffer[i]);
  }
  digitalWrite(PIN_SCE, HIGH); // disable screen
  blit=false;
}
Attachments
JVIDEO.zip
Player HEX
(9.24 KiB) Downloaded 238 times
Last edited by jonnection on Mon Mar 30, 2015 2:59 pm, edited 1 time in total.
User avatar
jonnection
 
Posts: 317
Joined: Sun May 04, 2014 8:21 pm

Re: Hammertime ! (video streaming with audio demo)

Postby erico » Wed Mar 18, 2015 8:03 pm

NICE! Did you convert the video before or is it something the gamebuino is kicking live?
I ask because I see you use a sort of noise or diffusion dither and I wonder if it could use a different technik.

Congrats! Also, nice choice of music! 8-)

[off topic on]
I was finishing this one game and then I was testing core animation for the final boss, here you see it :D
http://www.youtube.com/watch?v=o1mx3OcSamw
Is there something in common there? :D :D
PS: not showing video preview so not to interfere with yours.
[off topic off]
User avatar
erico
 
Posts: 671
Joined: Thu Mar 27, 2014 9:29 pm
Location: Brazil

Re: Hammertime ! (video streaming with audio demo)

Postby jonnection » Wed Mar 18, 2015 8:13 pm

It's done as follows:

- music is ripped out of the video using Audacity (well it actually uses ffmpeg so you could do it from command line as well) into 8-bit RAW
- video is ripped out as grayscale bmp file sequence at 84x48 using ffmpeg
- bitmap files are dithered (the question you were asking) using Floyd-Steinberg method with the "mogrify" tool in Imagemagick
- bitmap files are joined to a video frame stream using a program I wrote
- audio and video streams are interlaced together into 1 file using another simple prog I made

I'll put instructions and tools up as soon as I have time
User avatar
jonnection
 
Posts: 317
Joined: Sun May 04, 2014 8:21 pm

Re: Hammertime ! (video streaming with audio demo)

Postby erico » Wed Mar 18, 2015 8:48 pm

Nice, so on the 2nd and 3rd step I could do the video conversion my way and then get back to your pipeline with your code.
Pretty good! Congrats again! :)
User avatar
erico
 
Posts: 671
Joined: Thu Mar 27, 2014 9:29 pm
Location: Brazil

Re: Hammertime ! (video streaming with audio demo)

Postby jonnection » Thu Mar 19, 2015 8:40 pm

There was a small problem with my ripping tool: some 1bpp frames were inverted.

An updated, corrected video file has been uploaded.

EDIT: again, I'd really appreciate if someone with a REAL Gamebuino would try this to see how it works.
User avatar
jonnection
 
Posts: 317
Joined: Sun May 04, 2014 8:21 pm

Re: Hammertime ! (video streaming with audio demo)

Postby rodot » Fri Mar 20, 2015 7:03 am

Hey, that's really awesome ! :D


I've put your nickname in the title and a link to the forum thread in the description, but if you want me to remove it from my YouTube account (as it's not my work) just tell me.

PS: I would be glad to put it by default on all the Gamebuino I make if you add the ability to load the loader when C is pressed ^^
User avatar
rodot
Site Admin
 
Posts: 1290
Joined: Mon Nov 19, 2012 11:54 pm
Location: France

Re: Hammertime ! (video streaming with audio demo)

Postby Marcus » Fri Mar 20, 2015 7:48 am

Very nice! :-)

rodot wrote: I would be glad to put it by default on all the Gamebuino I make

Legal issues? Perhaps one of the open source 3D movies?
Marcus
 
Posts: 143
Joined: Fri Jan 09, 2015 6:51 pm

Re: Hammertime ! (video streaming with audio demo)

Postby jonnection » Fri Mar 20, 2015 11:31 am

rodot wrote:Hey, that's really awesome ! :D

I've put your nickname in the title and a link to the forum thread in the description, but if you want me to remove it from my YouTube account (as it's not my work) just tell me.

PS: I would be glad to put it by default on all the Gamebuino I make if you add the ability to load the loader when C is pressed ^^


Hey Rodot ! Thanks for making the video, I have no objection to it being on your channel. I was hoping that someone would make such a video.

I hope that I will have time to finalize this over the weekend:
- frame rate will be increased (15 fps works, I have already tested, probably 17-18 fps is doable)
- I will add 'c' button functionality once I check how it works in the Gamebuino lib now. I have to dl the latest repository and double check that I do it right
- I will also see if I can make it an actual Gamebuino program with menu and so. The only thing is that screen refresh has to be coordinated with incoming data, not by timing, as done by default in GB library
- I will publish the tools and the source to make videos yourself on this thread

The copyright issue that Marcus mentions is true. It would be safer to go with an open source / public domain (=something old) if you want to put ready on the card. I think fair use no longer applies when a series of copies are made & since you do charge a fee for the device.
User avatar
jonnection
 
Posts: 317
Joined: Sun May 04, 2014 8:21 pm

Re: Hammertime ! (video streaming with audio demo)

Postby Skyrunner65 » Sun Mar 22, 2015 1:34 pm

Hey Jonnection, if this had a file browser, it could be called complete.
I think this rivals the GW-Player or the Buino Player(especially).
(Also, for music, just do what Youtube Stars do and put a picture/animation acting as video)
User avatar
Skyrunner65
 
Posts: 371
Joined: Thu Mar 20, 2014 5:37 pm
Location: NC,USA

Re: Hammertime ! (video streaming with audio demo)

Postby jonnection » Sat Mar 28, 2015 6:47 pm

A-ha / Take on me



Did my best with sound quality and video fidelity this time
User avatar
jonnection
 
Posts: 317
Joined: Sun May 04, 2014 8:21 pm

Next

Return to Software Development

Who is online

Users browsing this forum: No registered users and 1 guest