1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#include <functional>
#include <memory>
#include <cerrno>
#include <sys/stat.h>
#include <string.h>
#include "wav.h"
#include "pcmengin.h"
using namespace std;
TWavHeader TWav::CreateHeader(int channels, uint32_t length) {
TWavHeader header;
uint32_t dataLen = length * 2 * channels;
const char dataString[] = "data";
header.RIFF[0] = 0x52;
header.RIFF[1] = 0x49;
header.RIFF[2] = 0x46;
header.RIFF[3] = 0x46;
header.ChunkSize = dataLen + sizeof(TWavHeader) - 8;;
header.WAVE[0] = 0x57;
header.WAVE[1] = 0x41;
header.WAVE[2] = 0x56;
header.WAVE[3] = 0x45;
header.fmt[0] = 0x66;
header.fmt[1] = 0x6d;
header.fmt[2] = 0x74;
header.fmt[3] = 0x20;
header.Subchunk1Size = 16;
header.AudioFormat = 1;
header.NumOfChan = channels;
header.SamplesPerSec = 44100; //samplerate;
header.bytesPerSec = 44100 * ((16 * channels) / 8);
header.blockAlign = 2 * channels;
header.bitsPerSample = 16;
strncpy(&header.Subchunk2ID[0], dataString, sizeof(dataString));
header.Subchunk2Size = dataLen;
return header;
}
TWav::TMeta TWav::ReadWavHeader(const string& filename) {
FILE* fd = fopen(filename.c_str(), "rb");
if (!fd)
throw TWavIOError("Can't open file to read", errno);
TWavHeader headerBuf;
if (fread(&headerBuf, sizeof(TWavHeader), 1, fd) != 1) {
const int errnum = errno;
fclose(fd);
throw TWavIOError("Can't read WAV header", errnum);
}
return {fd, headerBuf};
}
TWav::TMeta TWav::CreateFileAndHeader(const string& filename, const TWavHeader& header, bool overwrite) {
(void)overwrite;
FILE* fd = fopen(filename.c_str(), "wb");
if (!fd)
throw TWavIOError("Can't open file to write", errno);
if (fwrite(&header, sizeof(TWavHeader), 1, fd) != 1) {
const int errnum = errno;
fclose(fd);
throw TWavIOError("Can't write WAV header", errnum);
}
return {fd, header};
}
TWav::TWav(const string& filename)
: Meta(ReadWavHeader(filename)) {
}
TWav::TWav(const string& filename, const TWavHeader& header, bool overwrite)
: Meta(CreateFileAndHeader(filename, header, overwrite)) {
}
TWav::~TWav() {
fclose(Meta.WavFile);
}
const TWavHeader& TWav::GetWavHeader() const {
return Meta.Header;
}
|