/* * 2013 by Fabian Vogt */ #include #include #include #include #include #include #include "charmap.h" #include "audio.h" #include "filebrowser.h" uint16_t *screen; static inline void set_pixel(uint16_t x, uint8_t y, uint16_t value) { //if(likely(x < 320 && y < 240)) screen[x + y*320] = value; } void print_string(char* s1, uint16_t x, uint8_t y, uint16_t color) { uint8_t* s = (uint8_t*)s1; uint8_t x1; while(*s) { for(x1 = 0; x1 < 6; x1++) { if(charmap[*s][x1] & 1) set_pixel(x + x1, y + 0, color); if(charmap[*s][x1] & 2) set_pixel(x + x1, y + 1, color); if(charmap[*s][x1] & 4) set_pixel(x + x1, y + 2, color); if(charmap[*s][x1] & 8) set_pixel(x + x1, y + 3, color); if(charmap[*s][x1] & 16) set_pixel(x + x1, y + 4, color); if(charmap[*s][x1] & 32) set_pixel(x + x1, y + 5, color); if(charmap[*s][x1] & 64) set_pixel(x + x1, y + 6, color); } x += 6; s++; } } #define safe_malloc(var, bytes) \ var = malloc(bytes); \ if(!var)\ { \ show_msgbox("Error", "Out of Memory!"); \ return 1; \ } extern volatile uint32_t current; typedef struct WAVEHEADER { uint32_t RIFF; uint32_t size; uint32_t WAVE; uint32_t fmt; uint32_t format_length; uint16_t format_format; uint16_t channels; uint32_t samplerate; uint32_t avg_bytes_sec; uint16_t align; uint16_t bits_per_sample; } __attribute__((packed)) WAVEHEADER; int main(int argc, char** argv) { clrscr(); if(!lcd_isincolor()) { show_msgbox("Nope :P", "Only CX supported (yet)!"); return EXIT_FAILURE; } screen = SCREEN_BASE_ADDRESS; char* path; char strbuffer[100]; uint32_t samplerate; uint32_t* buffer; uint32_t buffer_size; if(argc == 1) { void* scrbuf; safe_malloc(scrbuf, SCREEN_BYTES_SIZE); int ret = filebrowser(scrbuf, strbuffer); if(ret == 1) return 1; path = strbuffer; } else path = argv[1]; memset(screen, 0xFF, 320*240*2); print_string("2013 by Fabian Vogt", 0, 230, 0); print_string("Loading file..", 0, 0, 0); FILE* music = fopen(path, "rb"); if(!music) { print_string("Failed to open!", 0, 10, 0); while(!isKeyPressed(KEY_NSPIRE_ESC)); return 1; } /* Load wav */ WAVEHEADER header; if(fread(&header, 1, sizeof(WAVEHEADER), music) != sizeof(WAVEHEADER) || header.RIFF != 0x46464952 || header.WAVE != 0x45564157) { print_string("Invalid wavefile!", 0, 10, 0); while(!isKeyPressed(KEY_NSPIRE_ESC)); return 1; } if(header.format_format != 1) { print_string("Wavefile not in PCM format!", 0, 10, 0); while(!isKeyPressed(KEY_NSPIRE_ESC)); return 1; } if(header.channels != 1) { print_string("Wavefile not mono!", 0, 10, 0); while(!isKeyPressed(KEY_NSPIRE_ESC)); return 1; } if(header.bits_per_sample != 8) { print_string("Not 8 bits per sample!", 0, 10, 0); while(!isKeyPressed(KEY_NSPIRE_ESC)); return 1; } uint32_t chunk[2]; while(1) { if(fread(chunk, 1, 8, music) != 8) { print_string("Corrupt wavefile!", 0, 10, 0); while(!isKeyPressed(KEY_NSPIRE_ESC)); return 1; } if(chunk[0] != 0x61746164) fseek(music, chunk[1], SEEK_CUR); else break; } safe_malloc(buffer, chunk[1]); buffer_size = fread(buffer, 1, chunk[1], music); if(buffer_size != chunk[1]) { free(buffer); print_string("Corrupt wavefile!", 0, 10, 0); while(!isKeyPressed(KEY_NSPIRE_ESC)); return 1; } samplerate = header.samplerate; sprintf(strbuffer, "Duration: %lu s", buffer_size / samplerate); print_string(strbuffer, 0, 10, 0); play(buffer, buffer_size, samplerate); print_string("Playing!", 0, 20, 0); uint32_t secs = 0; while(1) { //Display progress uint32_t new_secs = current / samplerate; if(new_secs < secs) memset(&(screen[320*30]), 0xFFFF, 6*320*2); secs = new_secs; set_pixel(secs, 30, 0); set_pixel(secs, 31, 0); set_pixel(secs, 32, 0); set_pixel(secs, 33, 0); set_pixel(secs, 34, 0); set_pixel(secs, 35, 0); if(isKeyPressed(KEY_NSPIRE_ESC)) break; } stop(); fclose(music); free(buffer); return EXIT_SUCCESS; }