diff options
| author | Ray <[email protected]> | 2018-10-29 16:18:06 +0100 |
|---|---|---|
| committer | Ray <[email protected]> | 2018-10-29 16:18:06 +0100 |
| commit | 298203a41a53a8b8eb78c51b2d4415b078efa474 (patch) | |
| tree | 545c8adcc880f4144ee8fe3f73d0c121f6e2cc68 /src/audio.c | |
| parent | 78064dee09f5dea69d4e5ffea9a1ba695bbd196c (diff) | |
| download | raylib-298203a41a53a8b8eb78c51b2d4415b078efa474.tar.gz raylib-298203a41a53a8b8eb78c51b2d4415b078efa474.zip | |
ADDED: Some functions...
text: IsEqualText() -WIP-
audio: SaveWAV()
audio: ExportWaveAsCode()
textures: ExportImageAsCode()
Diffstat (limited to 'src/audio.c')
| -rw-r--r-- | src/audio.c | 200 |
1 files changed, 128 insertions, 72 deletions
diff --git a/src/audio.c b/src/audio.c index f0362b2d..51023280 100644 --- a/src/audio.c +++ b/src/audio.c @@ -185,7 +185,8 @@ typedef enum { // Module specific Functions Declaration //---------------------------------------------------------------------------------- #if defined(SUPPORT_FILEFORMAT_WAV) -static Wave LoadWAV(const char *fileName); // Load WAV file +static Wave LoadWAV(const char *fileName); // Load WAV file +static int SaveWAV(Wave wave, const char *fileName); // Save wave data as WAV file #endif #if defined(SUPPORT_FILEFORMAT_OGG) static Wave LoadOGG(const char *fileName); // Load OGG file @@ -878,82 +879,57 @@ void ExportWave(Wave wave, const char *fileName) { bool success = false; - if (IsFileExtension(fileName, ".wav")) + if (IsFileExtension(fileName, ".wav")) success = SaveWAV(wave, fileName); + else if (IsFileExtension(fileName, ".raw")) { - // Basic WAV headers structs - typedef struct { - char chunkID[4]; - int chunkSize; - char format[4]; - } RiffHeader; - - typedef struct { - char subChunkID[4]; - int subChunkSize; - short audioFormat; - short numChannels; - int sampleRate; - int byteRate; - short blockAlign; - short bitsPerSample; - } WaveFormat; - - typedef struct { - char subChunkID[4]; - int subChunkSize; - } WaveData; + // Export raw sample data (without header) + // NOTE: It's up to the user to track wave parameters + FILE *rawFile = fopen(fileName, "wb"); + success = fwrite(wave.data, wave.sampleCount*wave.channels*wave.sampleSize/8, 1, rawFile); + fclose(rawFile); + } - RiffHeader riffHeader; - WaveFormat waveFormat; - WaveData waveData; - - // Fill structs with data - riffHeader.chunkID[0] = 'R'; - riffHeader.chunkID[1] = 'I'; - riffHeader.chunkID[2] = 'F'; - riffHeader.chunkID[3] = 'F'; - riffHeader.chunkSize = 44 - 4 + wave.sampleCount*wave.sampleSize/8; - riffHeader.format[0] = 'W'; - riffHeader.format[1] = 'A'; - riffHeader.format[2] = 'V'; - riffHeader.format[3] = 'E'; - - waveFormat.subChunkID[0] = 'f'; - waveFormat.subChunkID[1] = 'm'; - waveFormat.subChunkID[2] = 't'; - waveFormat.subChunkID[3] = ' '; - waveFormat.subChunkSize = 16; - waveFormat.audioFormat = 1; - waveFormat.numChannels = wave.channels; - waveFormat.sampleRate = wave.sampleRate; - waveFormat.byteRate = wave.sampleRate*wave.sampleSize/8; - waveFormat.blockAlign = wave.sampleSize/8; - waveFormat.bitsPerSample = wave.sampleSize; - - waveData.subChunkID[0] = 'd'; - waveData.subChunkID[1] = 'a'; - waveData.subChunkID[2] = 't'; - waveData.subChunkID[3] = 'a'; - waveData.subChunkSize = wave.sampleCount*wave.channels*wave.sampleSize/8; - - FILE *wavFile = fopen(fileName, "wb"); - - if (wavFile == NULL) return; - - fwrite(&riffHeader, 1, sizeof(RiffHeader), wavFile); - fwrite(&waveFormat, 1, sizeof(WaveFormat), wavFile); - fwrite(&waveData, 1, sizeof(WaveData), wavFile); + if (success) TraceLog(LOG_INFO, "Wave exported successfully: %s", fileName); + else TraceLog(LOG_WARNING, "Wave could not be exported."); +} - fwrite(wave.data, 1, wave.sampleCount*wave.channels*wave.sampleSize/8, wavFile); +// Export wave sample data to code (.h) +void ExportWaveAsCode(Wave wave, const char *fileName) +{ + #define BYTES_TEXT_PER_LINE 20 + + char varFileName[256] = { 0 }; + int dataSize = wave.sampleCount*wave.channels*wave.sampleSize/8; + + FILE *txtFile = fopen(fileName, "wt"); + + fprintf(txtFile, "\n//////////////////////////////////////////////////////////////////////////////////\n"); + fprintf(txtFile, "// //\n"); + fprintf(txtFile, "// WaveAsCode exporter v1.0 - Wave data exported as an array of bytes //\n"); + fprintf(txtFile, "// //\n"); + fprintf(txtFile, "// more info and bugs-report: github.com/raysan5/raylib //\n"); + fprintf(txtFile, "// feedback and support: ray[at]raylib.com //\n"); + fprintf(txtFile, "// //\n"); + fprintf(txtFile, "// Copyright (c) 2018 Ramon Santamaria (@raysan5) //\n"); + fprintf(txtFile, "// //\n"); + fprintf(txtFile, "//////////////////////////////////////////////////////////////////////////////////\n\n"); + + // Get file name from path and convert variable name to uppercase + strcpy(varFileName, GetFileNameWithoutExt(fileName)); + for (int i = 0; varFileName[i] != '\0'; i++) if (varFileName[i] >= 'a' && varFileName[i] <= 'z') { varFileName[i] = varFileName[i] - 32; } + + fprintf(txtFile, "// Wave data information\n"); + fprintf(txtFile, "#define %s_SAMPLE_COUNT %i\n", varFileName, wave.sampleCount); + fprintf(txtFile, "#define %s_SAMPLE_RATE %i\n", varFileName, wave.sampleRate); + fprintf(txtFile, "#define %s_SAMPLE_SIZE %i\n", varFileName, wave.sampleSize); + fprintf(txtFile, "#define %s_CHANNELS %i\n\n", varFileName, wave.channels); - fclose(wavFile); - - success = true; - } - else if (IsFileExtension(fileName, ".raw")) { } // TODO: Support additional file formats to export wave sample data + // Write byte data as hexadecimal text + fprintf(txtFile, "static unsigned char %s_DATA[%i] = { ", varFileName, dataSize); + for (int i = 0; i < dataSize - 1; i++) fprintf(txtFile, ((i%BYTES_TEXT_PER_LINE == 0) ? "0x%x,\n" : "0x%x, "), ((unsigned char *)wave.data)[i]); + fprintf(txtFile, "0x%x };\n", ((unsigned char *)wave.data)[dataSize - 1]); - if (success) TraceLog(LOG_INFO, "Wave exported successfully: %s", fileName); - else TraceLog(LOG_WARNING, "Wave could not be exported."); + fclose(txtFile); } // Play a sound @@ -1739,6 +1715,86 @@ static Wave LoadWAV(const char *fileName) return wave; } + +// Save wave data as WAV file +static int SaveWAV(Wave wave, const char *fileName) +{ + int success = 0; + int dataSize = wave.sampleCount*wave.channels*wave.sampleSize/8; + + // Basic WAV headers structs + typedef struct { + char chunkID[4]; + int chunkSize; + char format[4]; + } RiffHeader; + + typedef struct { + char subChunkID[4]; + int subChunkSize; + short audioFormat; + short numChannels; + int sampleRate; + int byteRate; + short blockAlign; + short bitsPerSample; + } WaveFormat; + + typedef struct { + char subChunkID[4]; + int subChunkSize; + } WaveData; + + FILE *wavFile = fopen(fileName, "wb"); + + if (wavFile == NULL) TraceLog(LOG_WARNING, "[%s] WAV audio file could not be created", fileName); + else + { + RiffHeader riffHeader; + WaveFormat waveFormat; + WaveData waveData; + + // Fill structs with data + riffHeader.chunkID[0] = 'R'; + riffHeader.chunkID[1] = 'I'; + riffHeader.chunkID[2] = 'F'; + riffHeader.chunkID[3] = 'F'; + riffHeader.chunkSize = 44 - 4 + wave.sampleCount*wave.sampleSize/8; + riffHeader.format[0] = 'W'; + riffHeader.format[1] = 'A'; + riffHeader.format[2] = 'V'; + riffHeader.format[3] = 'E'; + + waveFormat.subChunkID[0] = 'f'; + waveFormat.subChunkID[1] = 'm'; + waveFormat.subChunkID[2] = 't'; + waveFormat.subChunkID[3] = ' '; + waveFormat.subChunkSize = 16; + waveFormat.audioFormat = 1; + waveFormat.numChannels = wave.channels; + waveFormat.sampleRate = wave.sampleRate; + waveFormat.byteRate = wave.sampleRate*wave.sampleSize/8; + waveFormat.blockAlign = wave.sampleSize/8; + waveFormat.bitsPerSample = wave.sampleSize; + + waveData.subChunkID[0] = 'd'; + waveData.subChunkID[1] = 'a'; + waveData.subChunkID[2] = 't'; + waveData.subChunkID[3] = 'a'; + waveData.subChunkSize = dataSize; + + success = fwrite(&riffHeader, sizeof(RiffHeader), 1, wavFile); + success = fwrite(&waveFormat, sizeof(WaveFormat), 1, wavFile); + success = fwrite(&waveData, sizeof(WaveData), 1, wavFile); + + success = fwrite(wave.data, dataSize, 1, wavFile); + + fclose(wavFile); + } + + // If all data has been written correctly to file, success = 1 + return success; +} #endif #if defined(SUPPORT_FILEFORMAT_OGG) |
