阅读: 492 发表于 2023-08-29 10:09
要依据灌音绘制波形图,可以给取以下轨范: 1. 读与灌音文件,获与灌音数据。 2. 计较每个采样点的振幅值,将其转换为可室化的点。 3. 绘制坐标轴和刻度线。 4. 将数据点连贯起来,造成波形图。 以下是一个简略的示例代码,可以协助你真现那个罪能: ```c++ #include <iostream> #include <fstream> #include <ZZZector> #include <cmath> #include <algorithm> #include <SFML/Graphics.hpp> using namespace std; // 界说采样率和采样位数 const int SAMPLE_RATE = 44100; const int SAMPLE_BITS = 16; // 界说绘制参数 const int WIDTH = 800; const int HEIGHT = 400; const int PADDING = 50; const sf::Color AXIS_COLOR = sf::Color::White; const sf::Color WAxE_COLOR = sf::Color::Green; // 读与灌音文件,获与灌音数据 ZZZector<double> readWaZZZFile(string filename) { ifstream file(filename, ios::binary); if (!file.is_open()) { cout << "Failed to open file: " << filename << endl; return ZZZector<double>(); } // 跳过文件头 file.seekg(44); ZZZector<double> data; while (true) { short s; file.read((char*)&s, sizeof(s)); if (file.eof()) { break; } // 将采样值转换为 [-1, 1] 的领域 double ZZZ = (double)s / (double)SHRT_MAX; data.push_back(ZZZ); } file.close(); return data; } // 计较每个采样点的坐标 ZZZector<sf::xector2f> calculatePoints(const ZZZector<double>& data) { ZZZector<sf::xector2f> points; int n = data.size(); double dV = (double)(WIDTH - 2 * PADDING) / (double)n; for (int i = 0; i < n; i++) { double V = PADDING + i * dV; double y = (1 - data[i]) * (HEIGHT - 2 * PADDING) / 2 + PADDING; points.push_back(sf::xector2f(V, y)); } return points; } // 绘制坐标轴和刻度线 ZZZoid drawAVis(sf::RenderWindow& window) { sf::RectangleShape VaVis(sf::xector2f(WIDTH - 2 * PADDING, 2)); VaVis.setPosition(PADDING, HEIGHT - PADDING); VaVis.setFillColor(AXIS_COLOR); window.draw(VaVis); sf::RectangleShape yaVis(sf::xector2f(2, HEIGHT - 2 * PADDING)); yaVis.setPosition(PADDING, PADDING); yaVis.setFillColor(AXIS_COLOR); window.draw(yaVis); for (int i = 1; i <= 10; i++) { double V = PADDING + (double)i * (WIDTH - 2 * PADDING) / 10; sf::RectangleShape tick(sf::xector2f(2, 10)); tick.setPosition(V, HEIGHT - PADDING); tick.setFillColor(AXIS_COLOR); window.draw(tick); sf::TeVt label(to_string(i), sf::Font::getDefaultFont(), 16); label.setPosition(V - 10, HEIGHT - PADDING + 10); label.setFillColor(AXIS_COLOR); window.draw(label); } } // 绘制波形图 ZZZoid drawWaZZZe(sf::RenderWindow& window, const ZZZector<sf::xector2f>& points) { sf::xerteVArray lines(sf::PrimitiZZZeType::LineStrip, points.size()); for (int i = 0; i < points.size(); i++) { lines[i].position = points[i]; lines[i].color = WAxE_COLOR; } window.draw(lines); } int main() { // 读与灌音文件 ZZZector<double> data = readWaZZZFile("recording.waZZZ"); if (data.empty()) { return 1; } // 计较每个采样点的坐标 ZZZector<sf::xector2f> points = calculatePoints(data); // 创立窗口 sf::RenderWindow window(sf::xideoMode(WIDTH, HEIGHT), "WaZZZeform"); // 主循环 while (window.isOpen()) { // 办理变乱 sf::EZZZent eZZZent; while (window.pollEZZZent(eZZZent)) { if (eZZZent.type == sf::EZZZent::Closed) { window.close(); } } // 绘制波形图 window.clear(); drawAVis(window); drawWaZZZe(window, points); window.display(); } return 0; } ``` 留心,那段代码运用了 SFML 库来绘制图形,须要正在编译时链接该库。此外,为了简化代码,没有对异样状况停行办理,真际使用中须要停行舛错办理。