Пример проигрывания 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"]