1 /* 2 * libPCM by László Szerémi. 3 * Copyright under Boost License. 4 */ 5 6 module libPCM.file; 7 8 import core.stdc.stdio; 9 import core.stdc.stdlib; 10 import std.stdio; 11 import std.conv; 12 version(Windows){ 13 import core.sys.windows.windows; 14 }else version(Posix){ 15 import core.stdc.errno; 16 } 17 18 import libPCM.types; 19 import libPCM.common; 20 import libPCM.utility; 21 22 public: 23 /** 24 * Loads a *.pcm file into the memory. 25 */ 26 PCMFile loadPCMFile(immutable char* name){ 27 FILE* inputStream = fopen(name, "rb"); 28 if(inputStream is null){ 29 import std.conv; 30 version(Windows){ 31 DWORD errorCode = GetLastError(); 32 }else version(Posix){ 33 int errorCode = errno; 34 } 35 36 throw new AudioFileException("File access error! Error number: " ~ to!string(errorCode)); 37 } 38 PCMFile file; 39 void* buffer; 40 char* tagData; 41 fread(&file.header, PCMHeader.sizeof, 1, inputStream); 42 size_t tagData_l = (file.header.author_l + file.header.comment_l + file.header.copyright_l + file.header.name_l) * 4; 43 if(tagData_l){ 44 tagData = cast(char*)malloc(tagData_l); 45 fread(tagData, tagData_l, 1, inputStream); 46 file.loadTagData(tagData); 47 free(tagData); 48 } 49 size_t sampleSize, sampleLength; 50 version(x64){ 51 sampleLength = (file.header.length + file.header.length_h<<32); 52 sampleSize = sampleLength * (getWordLength(file.header.codecType)/8); 53 }else{ 54 sampleLength = file.header.length; 55 sampleSize = sampleLength * (getWordLength(file.header.codecType)/8); 56 } 57 58 file.data = new WaveData(sampleLength, file.header.sampleRate, file.header.codecType, sampleSize, file.header.numOfChannels); 59 60 fread(file.data.data.ptr, sampleSize, 1, inputStream); 61 62 fclose(inputStream); 63 return file; 64 } 65 /** 66 * Loads a *.wav file into the memory. 67 */ 68 WavFile loadWavFile(immutable char* name){ 69 FILE* inputStream = fopen(name, "rb"); 70 if(inputStream is null){ 71 import std.conv; 72 version(Windows){ 73 DWORD errorCode = GetLastError(); 74 }else version(Posix){ 75 int errorCode = errno; 76 } 77 throw new AudioFileException("File access error! Error number: " ~ to!string(errorCode)); 78 } 79 WavFile file = new WavFile; 80 void* buffer; 81 fread(&file.riff, file.riff.sizeof, 1, inputStream); 82 fread(&file.subchunk1, file.subchunk1.sizeof, 1, inputStream); 83 fread(&file.subchunk2, file.subchunk2.sizeof, 1, inputStream); 84 85 uint sampleLength = file.subchunk2.subchunk2Size / file.subchunk1.numOfChannels / 86 (getWordLength(fromWAVAudioFormat(file.subchunk1.audioFormat, file.subchunk1.bitsPerSample)) / 8); 87 file.data = new WaveData(sampleLength, to!float(file.subchunk1.sampleRate), fromWAVAudioFormat(file.subchunk1.audioFormat, file.subchunk1.bitsPerSample), 88 file.subchunk2.subchunk2Size, cast(ubyte)file.subchunk1.numOfChannels); 89 fread(file.data.data.ptr, file.subchunk2.subchunk2Size,1 , inputStream); 90 91 fclose(inputStream); 92 free(buffer); 93 return file; 94 } 95 /** 96 * Stores a *.wav file. 97 */ 98 void storeWavFile(WavFile file, immutable char* name){ 99 FILE* outputStream = fopen(name, "wb"); 100 if(outputStream is null){ 101 import std.conv; 102 version(Windows){ 103 DWORD errorCode = GetLastError(); 104 }else version(Posix){ 105 int errorCode = errno; 106 } 107 throw new AudioFileException("File access error! Error number: " ~ to!string(errorCode)); 108 } 109 fwrite(&(file.riff), WavHeaderMain.sizeof, 1, outputStream); 110 fwrite(&(file.subchunk1), WavHeaderSubchunk1.sizeof, 1, outputStream); 111 fwrite(&(file.subchunk2), WavHeaderSubchunk2.sizeof, 1, outputStream); 112 fwrite(file.data.data.ptr, file.data.data.length, 1, outputStream); 113 fclose(outputStream); 114 } 115 /** 116 * Stores a *.pcm file. 117 */ 118 void storePCMFile(PCMFile file, immutable char* name){ 119 FILE* outputStream = fopen(name, "wb"); 120 if(outputStream is null){ 121 import std.conv; 122 version(Windows){ 123 DWORD errorCode = GetLastError(); 124 }else version(Posix){ 125 int errorCode = errno; 126 } 127 throw new AudioFileException("File access error! Error number: " ~ to!string(errorCode)); 128 } 129 fwrite(&(file.header), PCMHeader.sizeof, 1, outputStream); 130 fwrite(file.data.data.ptr, file.data.data.length, 1, outputStream); 131 132 fclose(outputStream); 133 }