bool RageSurfaceUtils::SaveBMP( RageSurface *surface, RageFile &f ) { /* Convert the surface to 24bpp. */ RageSurface *converted_surface; converted_surface = CreateSurface( surface->w, surface->h, 24, Swap24LE( 0xFF0000 ), Swap24LE( 0x00FF00 ), Swap24LE( 0x0000FF ), 0 ); RageSurfaceUtils::CopySurface( surface, converted_surface ); RString sError; int iFilePitch = converted_surface->pitch; iFilePitch = (iFilePitch+3) & ~3; // round up a multiple of 4 int iDataSize = converted_surface->h * iFilePitch; const int iHeaderSize = 0x36; WriteBytes( f, sError, "BM", 2 ); write_le32( f, sError, iHeaderSize+iDataSize ); // size (offset 0x2) write_le32( f, sError, 0 ); // reserved (offset 0x6) write_le32( f, sError, iHeaderSize ); // bitmap offset (offset 0xA) write_le32( f, sError, 0x28 ); // header size (offset 0xE) write_le32( f, sError, surface->w ); // width (offset 0x14) write_le32( f, sError, surface->h ); // height (offset 0x18) write_le16( f, sError, 1 ); // planes (offset 0x1A) write_le16( f, sError, (uint16_t) converted_surface->fmt.BytesPerPixel*8 ); // bpp (offset 0x1C) write_le32( f, sError, 0 ); // compression (offset 0x1E) write_le32( f, sError, iDataSize ); // bitmap size (offset 0x22) write_le32( f, sError, 0 ); // horiz resolution (offset 0x26) write_le32( f, sError, 0 ); // vert resolution (offset 0x2A) write_le32( f, sError, 0 ); // colors (offset 0x2E) write_le32( f, sError, 0 ); // important colors (offset 0x32) for( int y = converted_surface->h-1; y >= 0; --y ) { const uint8_t *pRow = converted_surface->pixels + converted_surface->pitch*y; WriteBytes( f, sError, pRow, converted_surface->pitch ); /* Pad the row to the pitch. */ uint8_t padding[4] = { 0,0,0,0 }; WriteBytes( f, sError, padding, iFilePitch-converted_surface->pitch ); } delete converted_surface; if( sError.size() != 0 ) return false; if( f.Flush() == -1 ) return false; return true; }
int main() { output_file = fopen("output.wav", "wb"); if (!output_file) die_perror("failed to open file"); int samplerate = SAMPLE_RATE; int channels = 2; int bitspersample = 16; int datarate = samplerate * channels * (bitspersample / 8); int blockalign = channels * (bitspersample / 8); // write wav header output_write("RIFF", 4); long riff_len_pos = ftell(output_file); // need to write 36+datalen to riff_len_pos write_le32(0); output_write("WAVE", 4); output_write("fmt ", 4); write_le32(16); write_le16(1); write_le16(channels); write_le32(samplerate); write_le32(datarate); write_le16(blockalign); write_le16(bitspersample); output_write("data", 4); long wav_data_pos = ftell(output_file); // need to write datalen to wav_data_pos write_le32(0); int i; for (i = 0; i < 22050; i++) output_sample(0, 0); // write 500ms of silence write_pulse(1, 4909, 1000000); // command start write_pulse(0, 4320, 1000000); i = 0; unsigned code = 0xe0e040bf; for (i = 0; i < 32; i++) { int bit = (code >> (31 - i)) & 0x1; if (bit) { write_pulse(1, 818, 1000000); // 1 bit write_pulse(0, 1425, 1000000); } else { write_pulse(1, 818, 1000000); // 0 bit write_pulse(0, 325, 1000000); } } write_pulse(1, 717, 1000000); // command stop write_pulse(0, 717, 1000000); for (i = 0; i < 22050; i++) output_sample(0, 0); // write 500ms of silence fseek(output_file, riff_len_pos, SEEK_SET); write_le32(36 + datalen); fseek(output_file, wav_data_pos, SEEK_SET); write_le32(datalen); fclose(output_file); return 0; }