Проигрывание RSF из EEPROM

Пример проигрывания RSF файлов из EEPROM (Arduino)



Структура образа загружаемого в EEPROM

смещение  размер       описание
0         1 байт       количество мелодий

1         2 байта      смещение от начала образа до мелодии 1
3         2 байта      общее число фреймов в мелодии 1

5         2 байта      смещение от начала образа до мелодии 2
7         2 байта      общее число фреймов в мелодии 2
..........

X         2 байта      смещение от начала образа до мелодии N
X         2 байта      общее число фреймов в мелодии N

X                      содержимое RSF файла 1

X                      содержимое RSF файла 2

X                      содержимое RSF файла 3
...........

X                      содержимое RSF файла N

Инициализации и запуск мелодий

Wire.begin();
songs = readEEPROM(disk1, 0);
Serial.begin(19200); // 57600 для версий 14.0+
for(int i=0; i<songs; i++) playsong(i);

Functions

byte readEEPROM(int deviceaddress, unsigned int eeaddress )
{
  byte rdata = 0;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.read();
  return rdata;
}

Функция PlaySong для версий эмулятора до 13.2 включительно

void playsong(byte num)
{
  int offset = readEEPROM(disk1, 1 + num*4) + readEEPROM(disk1, 1 + num*4 + 1)*256;
  int frames = readEEPROM(disk1, 1 + num*4 + 2) + readEEPROM(disk1, 1 + num*4 + 3)*256;

  offset += 16; //RSF header

  int frame = 0;
  byte tmp;

  byte writebuf[16];
  memset(writebuf,0,14);
  writebuf[14] = 0x80;
  writebuf[15] = 0x7F;


  unsigned int tmp2, skip;

  while( frame < frames )
  {
    skip = 1;
    tmp = readEEPROM(disk1, offset++);
    if(tmp == 0xFE)
    {
         tmp = readEEPROM(disk1, offset++);
         skip = tmp * 16;
    }
    else if(tmp == 0xFD)
    {
         tmp = readEEPROM(disk1, offset++);
         skip = tmp * 2;
    }
    else if(tmp != 0xFF)
    {
         tmp2 = tmp * 256;
         tmp2 += readEEPROM(disk1, offset++);
         byte reg = 0;
         writebuf[13] = 0xFF;
         while(tmp2 > 0 && reg < 14)
         {
             if(tmp2 & 1 == 1)
             {
                 writebuf[reg] = readEEPROM(disk1, offset++);
             }
             tmp2 >>= 1;
             reg++;
         }
         Serial.write(writebuf,16);
     }
     for(int i = 1; i <= skip; i++) delay(20);

     frame += skip;
  }
  //stop
  memset(writebuf,0,14);
  writebuf[7] = 63;
  Serial.write(writebuf,16);
}

Функция PlaySong  для версий эмулятора 14.0+ (не проверялась)

void playsong(byte num)
{
   int offset = readEEPROM(disk1, 1 + num*4) + readEEPROM(disk1, 1 + num*4 + 1)*256;
   int frames = readEEPROM(disk1, 1 + num*4 + 2) + readEEPROM(disk1, 1 + num*4 + 3)*256;

   offset += 16; //RSF header

   int frame = 0;
   byte tmp, tmp3;

   byte writebuf[16];

   //mute
   memset(writebuf,0,14);
   writebuf[7] = 63;

   for(int i = 0; i <14; i++) {
      Serial.write(i,1);
      Serial.write(writebuf[i],1);
   }

   memset(writebuf,0,14);
   writebuf[13] = 0xFF;

   Serial.write(writebuf[13],1); // to synchronize

   unsigned int tmp2, skip;

   while( frame < frames )
   {
       skip = 1;
       tmp = readEEPROM(disk1, offset++);
       if(tmp == 0xFE)
       {
           tmp = readEEPROM(disk1, offset++);
           skip = tmp * 16;
       }
       else if(tmp == 0xFD)
       {
           tmp = readEEPROM(disk1, offset++);
           skip = tmp * 2;
       }
       else if(tmp != 0xFF)
       {
           tmp2 = tmp * 256;
           tmp2 += readEEPROM(disk1, offset++);
           byte reg = 0;
           while(tmp2 > 0 && reg < 14)
           {
               if(tmp2 & 1 == 1)
               {
                   tmp3 = readEEPROM(disk1, offset++);
                   if(writebuf[reg] != tmp3)
                   {
                       writebuf[reg] = tmp3;
                       if(!(reg==13 && tmp3==0xFF))
                       {
                           Serial.write(reg,1);
                           Serial.write(tmp3,1);
                       }
                   }
               }
               tmp2 >>= 1;
               reg++;
           }
       }
       for(int i = 1; i <= skip; i++) delay(20);
       frame += skip;
   }
   //mute
   memset(writebuf,0,14);
   writebuf[7] = 63;

   for(int i = 0; i <14; i++) {
       Serial.write(i,1);
       Serial.write(writebuf[i],1);
   }
}

[ad name="HTML"]

Добавить комментарий

Ваш адрес email не будет опубликован.