프로그래밍 언어2022. 9. 14. 01:59

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
#include <iostream>
#include <filesystem>
#include <fstream>
#include <cmath>
#include <limits>
 
static constexpr int SAMPLES_PER_MS_FOR_16K = 16;
static constexpr int SAMPLES_60MS_FOR_16K = SAMPLES_PER_MS_FOR_16K * 60;
static constexpr double MAX_SAMPLE_VALUE = 32768.0; // 2^(n - 1) = 2^(16-1) = 2^15 = 32768
 
double getRmsInDecibel(const double meanSquareValue, const int sampleCount)
{
    if (sampleCount <= 0) {
        return std::numeric_limits<double>::quiet_NaN();
    }
 
#ifdef _DEBUG
    double RMS = meanSquareValue / sampleCount;
    const double SQRT_RMS = std::sqrt(RMS);
    const double LOG_10 = std::log10(SQRT_RMS / MAX_SAMPLE_VALUE);
    const double LOG_10_TIMES_20 = 20 * LOG_10 + 3.01;
    return RMS = LOG_10_TIMES_20;
#else
    return 20 * std::log10(std::sqrt(meanSquareValue / sampleCount) / MAX_SAMPLE_VALUE) + 3.01; // FS sine wave vs. FS square wave
#endif
}
 
int main(int argc, char* argv[])
{
    if (argc <= 1) {
        std::cout << "argc is less than or equal to one\n";
        return -1;
    }
 
    std::filesystem::path pcmSource{ argv[1], std::filesystem::path::auto_format };
    std::ifstream fin{ pcmSource.native(), std::ios_base::binary };
 
    if (!fin.is_open()) {
        std::cerr << "Fail to open file " << pcmSource.filename() << ".\n";
        return -1;
    }
 
    std::cout << "Read PCM data from " << pcmSource.filename() << "\n";
 
    short min = std::numeric_limits<short>::max();
    short max = std::numeric_limits<short>::min();
 
    int count = 0;
    double RMS = 0;
 
    while (!fin.eof()) {
        short frame = 0;
        fin.read(reinterpret_cast<char*>(&frame), sizeof frame);
 
        min = std::min(frame, min);
        max = std::max(frame, max);
 
        RMS += (frame * frame);
 
        if (++count % SAMPLES_60MS_FOR_16K == 0) {
            RMS = getRmsInDecibel(RMS, SAMPLES_60MS_FOR_16K);
 
            std::cout << "[ " << count << " ]\n";
            std::cout << "max: " << max << ", min: " << min << '\n';
            std::cout << "RMS: " << RMS << "dB\n";
 
            max = std::numeric_limits<short>::min();
            min = std::numeric_limits<short>::max();
            RMS = 0.0;
        }
    }
 
    std::cout << "[ " << count << " ]\n";
    std::cout << "max: " << max << ", min: " << min << '\n';
    std::cout << "RMS: " << getRmsInDecibel(RMS, SAMPLES_60MS_FOR_16K) << "dB\n";
 
    return 0;
}

Posted by 세월의돌
잡담2022. 4. 25. 10:43

셀의 표시형식을

“사용자 지정” > “[h]:mm;@”

으로 설정하면 된다.

Posted by 세월의돌