#include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "dr_wav.h" #include "embed.h" #include "util.h" #include "wavelet.h" //#include "miniaudio.h" #include "dr_mp3.h" using namespace std; using namespace cv; namespace fs = std::filesystem; using namespace Eigen; const int k1 = 5; const double PI = 3.1416; int G_L = 0; const int G_NMAX_32 = 40; const int G_SIZE_32 = 2 * G_NMAX_32 + 1; const int G_TOTAL_ELEMENTS_32 = G_SIZE_32 * G_SIZE_32; vector> G_ZMLIST_32(G_TOTAL_ELEMENTS_32, vector(2, 0)); vector> G_A_NM_32(G_TOTAL_ELEMENTS_32, (0, 0)); vector> G_ZMLIST_SELECTED_32(G_TOTAL_ELEMENTS_32, vector(2, 0)); const int G_NMAX_10 = 20; const int G_SIZE_10 = 2 * G_NMAX_10 + 1; const int G_TOTAL_ELEMENTS_10 = G_SIZE_10 * G_SIZE_10; vector> G_ZMLIST_10(G_TOTAL_ELEMENTS_10, vector(2, 0)); vector> G_A_NM_10(G_TOTAL_ELEMENTS_10, (0, 0)); vector> G_ZMLIST_SELECTED_10(G_TOTAL_ELEMENTS_10, vector(2, 0)); vector> G_A_NM_SELECTED; vector> G_A_NM_MODIFIED; vector>> G_GP_REC_BEFOREMODIFY; vector>> G_GP_REC; int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const int wm_size, const double start_time, const double end_time) { if (!canFormSquareMatrix(wm_size)) return 2; int is_mp3 = 0; int Fs = 0; int wavelength = 0; //double D = 0.8; // init 0.2 double DD = 0.0012; // init DD 0.0012 double EE = 0.00002; // init EE 0.00002 int begin = 4095; int block_length = 0; vector syn = {1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0}; const int Lsyn = syn.size(); fs::path fname = path; fs::path s_path = save_path; int channels; //int bitrate; vector yo; vector yo_origin; int start = 0; string audio_name = ConvertUTF16ToMBCS(path); string save_name = ConvertUTF16ToMBCS(save_path); cout << "\n read file:" << audio_name << endl; if (isMp3File(fname, audio_name)) { // is mp3 is_mp3 = 1; long Fs_long = 0; yo_origin = mp3ToDoubleVector(audio_name.c_str(), channels, Fs_long, wavelength); Fs = (int)Fs_long; } else { drwav wav; if (!drwav_init_file(&wav, audio_name.c_str(), nullptr)) { std::cerr << "Error opening WAV file." << std::endl; return 1; } yo_origin = readWav(wav, wavelength, channels, Fs); } // stage 1 end if ((end_time - start_time) < 25.0) // The difference between start_time and end_time is not less than 25 seconds return 4; //int r = static_cast(wavelength) / Fs; //double embed_range = ceil(r * 0.58); //if ((end_time - start_time) < embed_range) { // cout << "[embed error] Please increase the embedding range to " << embed_range << " seconds or more." << endl; // return 6; //} if (Fs < 44100) { wstring resample_path = AddSuffixToPath(path, L"_resample"); vector out; convert_wav(yo_origin, Fs, channels, resample_path.c_str()); } int max_wavelength = Fs * static_cast(end_time - start_time) * channels; // stage 1 start //const int frame_size = max_wavelength; // 每帧大小 //const int hop_size = Fs; // 帧移 //size_t num_frames = (yo_origin.size() - frame_size) / hop_size + 1; //std::vector energy(num_frames); //// Calculate short-term energy //for (size_t i = 0; i < num_frames; ++i) { // double frame_energy = 0.0; // for (int j = 0; j < frame_size; ++j) { // frame_energy += yo_origin[i * hop_size + j] * yo_origin[i * hop_size + j]; // } // energy[i] = frame_energy; //} //// Calculate the mean and standard deviation of energy //double mean_energy = std::accumulate(energy.begin(), energy.end(), 0.0) / num_frames; //double sq_sum = std::inner_product(energy.begin(), energy.end(), energy.begin(), 0.0); //double stddev_energy = std::sqrt(sq_sum / num_frames - mean_energy * mean_energy); //// Set a threshold, such as adding twice the standard deviation to the mean //double threshold = mean_energy + 2 * stddev_energy; //// Detect noisy areas //for (size_t i = 0; i < num_frames; ++i) { // if (energy[i] > threshold) { // start = i * hop_size; // std::cout << "Noisy frame detected at frame index: " << i << ", yo_origin[" << i * hop_size << "], sec: " << static_cast(i * hop_size) / (Fs * 2) << "s,Energy: " << energy[i] << std::endl; // // 将噪杂的帧添加到yo中 // for (int j = 0; j < max_wavelength; ++j) { // yo.push_back(yo_origin[start + j]); // } // wavelength = max_wavelength / channels; // break; // } //} bool split = yo_origin.size() > max_wavelength; if (yo.empty()) { // 如果音频长度大于25s 则根据start_time, end_time 来确定要嵌入水印的范围 // getAudio20sFront(split, max_wavelength, Fs, channels, wavelength, yo_origin, yo); if (split) { start = static_cast(start_time) * Fs * channels; cout << "start: " << start << endl; splitAudioByTime(max_wavelength, Fs, channels, wavelength, yo_origin, yo, start_time, end_time, start); } else { yo = yo_origin; } } vector> audio_data(yo.size() / channels, vector(channels, 0.0)); cout << "yo.size():" << yo.size() << endl; cout << "audio_data.size():" << audio_data.size() << endl; if (channels == 2) { for (int i = 0; i < yo.size(); i++) { if (i % 2 == 0) { audio_data[i / 2][0] = yo[i]; } if (i % 2 == 1) { audio_data[i / 2][1] = yo[i]; } } } else { for (int i = 0; i < yo.size(); i++) { audio_data[i][0] = yo[i]; } } std::vector wm_vector(wm, wm + wm_size); //vector> ww_matrix = matToVector(ww, rows, cols); int row = static_cast(std::sqrt(wm_size)); vector> ww_matrix = int_ott(wm_vector, row); int rows = ww_matrix.size(); int cols = ww_matrix[0].size(); cout << "ww_rows:" << ww_matrix.size() << "\t ww_cols:" << ww_matrix[0].size() << endl; // 图像置乱 vector> w = general(ww_matrix, rows, cols, 5, 6); // 降维 vector w1 = int_tto(w, rows); //block_length = rows * cols * 8 * 8; block_length = 65536; int i = 1; //int left = i * (Lsyn * k1 + block_length); int right = wavelength - (Lsyn * k1 + block_length) * 2; vector t0; while (i * (Lsyn * k1 + block_length) < wavelength - ((Lsyn * k1 + block_length))) { int bb = begin + (i - 1) * (Lsyn * k1 + block_length); cout << "\n embed barker code form " << bb << " to " << bb + Lsyn * k1 << endl; for (int mm = 0; mm < Lsyn; mm++) { //vector temp_vec_subsyn; int front = bb + (mm * k1); int back = bb + ((mm + 1) * k1); //计算指定范围均值 double tempmean = calculateMean(audio_data, front + 1, back, 0); // front = 4096 back = 4100 int temp = static_cast(floor(tempmean / D)); double tempmeanl; if ((temp % 2 + 2) % 2 == syn[mm]) { tempmeanl = temp * D + D / 2.0; } else { tempmeanl = temp * D - D / 2.0; } // 更新指定范围的yo for (int j = front; j <= back; j++) { audio_data[j][0] += tempmeanl - tempmean; } } t0.push_back(begin + (i * Lsyn * k1) + ((i - 1) * block_length) + 1); vector BLOCK1; for (int j = t0[i - 1]; j < t0[i - 1] + block_length; j++) { BLOCK1.push_back(audio_data[j][0]); } vector result = wavelet(BLOCK1, 1); result.resize(65536); BLOCK1.clear(); vector> I = ott(result, 256); int n = I.size(); // 行数 int m = I[0].size(); // 列数 // 极坐标转换相关参数 int M = 4 * n; //vector> fp(M, vector(M, 0.0)); //vector> Gp(M, vector(M, 0.0)); vector> rr(M, vector(M, 0.0)); vector> oo(M, vector(M, 0.0)); // 声明和初始化 vv 和 uu 矩阵 vector> vv(M, vector(M, 0)); vector> uu(M, vector(M, 0)); MatrixXd fp(M, M); MatrixXd Gp(M, M); // 填充 fp 和 Gp 数组 for (int u = 0; u < M; u++) { for (int v = 0; v < M; v++) { double rrr = static_cast (u) / M; double ooo = (2 * PI * v) / M; int kk = ceil(rrr * (n / 2) * sin(ooo)); int ll = ceil(rrr * (n / 2) * cos(ooo)); fp(u, v) = I[(-1) * kk + (n / 2)][ll + (n / 2) - 1]; Gp(u, v) = fp(u, v) * std::sqrt(static_cast (u) / (2 * M)); } } // 填充 vv 和 uu 矩阵 for (int k = 0; k < M; k++) { for (int j = 0; j < M; j++) { vv[k][j] = j + 1; uu[k][j] = k + 1; } } // 计算 rr 和 oo 矩阵 for (int k = 0; k < M; k++) { for (int j = 0; j < M; j++) { rr[k][j] = static_cast(uu[k][j] - 1) / M; oo[k][j] = static_cast(2 * PI * (vv[k][j] - 1)) / M; } } vector> Gp_watermarked(M, vector(M, 0.0)); PQIMfft_embed(Gp, fp, w1, M, DD, EE, oo, rr, Gp_watermarked); cout << "初始化 I_incircle 为全零矩阵" << endl; vector> I_incircle(n, vector(m, 0.0)); // 嵌入水印 cout << "\n 嵌入水印" << endl; for (int u = 0; u < M; u++) { for (int v = 0; v < M; v++) { double r = static_cast(u) / M; double o = (2 * PI * v) / M; int kkk = static_cast(std::ceil(r * (n / 2) * std::sin(o))); int lll = static_cast(std::ceil(r * (n / 2) * std::cos(o))); I_incircle[-kkk + (n / 2)][lll + (n / 2) - 1] = Gp_watermarked[u][v]; } } // 重构水印 cout << "重构水印" << endl; // vector> I_watermarked = I_incircle; cout << "I_incircle's rows:" << I_incircle.size() << "I_incircle's cols: " << I_incircle[0].size() << endl; for (int ii = 0; ii < n; ii++) { for (int jj = 0; jj < m; jj++) { if (I_incircle[ii][jj] == 0) { I_incircle[ii][jj] = I[ii][jj]; } } } cout << "\n go to tto;" << endl; vector BLOCK2 = tto(I_incircle, 256); vector new_BLOCK2(BLOCK2.size(), 0.0); BLOCK2.insert(BLOCK2.end(), new_BLOCK2.begin(), new_BLOCK2.end()); cout << "\n go to inverseWavelet;" << endl; vector signal = inverseWavelet(BLOCK2, 1); //cout << "\n NO." << i << " , form " << t0[i - 1] << " to " << t0[i - 1] + block_length - 1 << endl; for (int j = t0[i - 1]; j < t0[i - 1] + block_length; j++) { audio_data[j][0] = signal[j - t0[i - 1]]; } double sub_progress = double(i * (Lsyn * k1 + block_length)) / (wavelength - (Lsyn * k1 + block_length) * 2) * 100; g_audio_wm_progress = sub_progress; cout << "\n 总完成进度:" << sub_progress << endl; cout << "==============================================================" << endl; i++; //left = i * (Lsyn * k1 + block_length); } cout << "t0:" << endl; printIntSignal(t0, 0); //trans audio_data to yo yo.clear(); if (channels == 2) { for (int j = 0; j < audio_data.size(); j++) { yo.push_back(audio_data[j][0]); yo.push_back(audio_data[j][1]); } } else { for (int j = 0; j < audio_data.size(); j++) { yo.push_back(audio_data[j][0]); } } cout << "yo.size: " << yo.size() << endl; printSignal(yo, 10); cout << "start: " << start << endl; if (split) { for (size_t i = 0; i < yo.size(); ++i) { yo_origin[start + i] = yo[i]; } } else { yo_origin = yo; } // save audio //if (s_path.extension() != ".wav") // s_path.replace_extension(".wav"); const wchar_t* wchar_save_path = s_path.c_str(); // 使用完整的保存路径 if (is_mp3) { save_audio_drmp3(wchar_save_path, yo_origin, Fs, channels); } else { save_audio_drwav(wchar_save_path, yo_origin, Fs, channels); } //fs::remove(fname); return 0; } void saveAudio(const char* outputFilename, vector &yo, int sampleRate, int channels) { SF_INFO sfinfo{}; sfinfo.samplerate = sampleRate; // 设置采样率 sfinfo.channels = channels; // 设置声道数 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; // 设置文件格式 // todo save audio SNDFILE* outfile = sf_open(outputFilename, SFM_WRITE, &sfinfo); sf_count_t count = sf_write_double(outfile, yo.data(), yo.size()); cout << "\n保存地址:" << outputFilename << endl; if (count != yo.size()) { std::cerr << "Error writing frames to file" << std::endl; sf_close(outfile); return; } // 关闭文件 sf_close(outfile); std::cout << "\nFile saved successfully." << std::endl; } vector inverseWavelet(vector swt_output, int level) { vector iswt_output; iswt(swt_output, level, "haar", iswt_output); return iswt_output; } void PQIMfft_embed(MatrixXd Gp, MatrixXd fp, vector &w1, int M, double DD, double EE, vector> &oo, vector> &rr, vector> &Gp_watermarked) { G_L = w1.size(); int row = static_cast(std::sqrt(G_L)); vector> zmlist; vector> zmlist_selected; vector> a_nm; int nmax = 0; if (row == 10) { nmax = G_NMAX_10; a_nm = G_A_NM_10; zmlist = G_ZMLIST_10; } else { nmax = G_NMAX_32; a_nm = G_A_NM_32; zmlist = G_ZMLIST_32; } zhishujufenjie62(Gp, M, nmax, a_nm, zmlist); // 对应的n和m vector index_n(zmlist.size(), 0); vector index_m(zmlist.size(), 0); for (int i = 0; i < zmlist.size(); i++) { index_n[i] = zmlist[i][0]; index_m[i] = zmlist[i][1]; } // 找到合适的嵌入位置 vector index_suitable; for (int i = 0; i < zmlist.size(); i++) { if (row == 10) { // 10*10 embed range if (((index_m[i] == 0) && (index_n[i] < 0)) || ((index_m[i] > 0) && (index_m[i] <= 10) && (-4 <= index_n[i]) && (index_n[i] <= 4))) { index_suitable.push_back(i); } } else { // 32*32 embed range if (((index_m[i] == 0) && (index_n[i] < 0)) || ((index_m[i] > 0) && (index_m[i] <= 30) && (-16 <= index_n[i]) && (index_n[i] <= 16))) { index_suitable.push_back(i); } } } index_n.clear(); index_m.clear(); // 随机选出嵌入水印的位置 vector index_selected_embed(index_suitable.begin(), index_suitable.begin() + G_L); index_suitable.clear(); // 得到在zmlist中的对应的数据,为下一步重构准备的 //G_ZMLIST_SELECTED_10.resize(G_L, vector(2, 0)); zmlist_selected.resize(G_L, vector(2, 0)); G_A_NM_SELECTED.resize(G_L, (0,0)); for (int i = 0; i < G_L; i++) { //G_ZMLIST_SELECTED_10[i] = G_ZMLIST_10[index_selected_embed[i]]; zmlist_selected[i] = zmlist[index_selected_embed[i]]; G_A_NM_SELECTED[i] = a_nm[index_selected_embed[i]]; } index_selected_embed.clear(); G_A_NM_MODIFIED = G_A_NM_SELECTED; vector III(G_L, 0.0); vector IIII(G_L, 0.0); for (int i = 0; i < G_L; i++) { complex A_selected = G_A_NM_MODIFIED[i]; III[i] = ((-DD) + sqrt(pow(DD, 2) + 2 * EE * abs(A_selected))) / EE; double flag = 2 * floor((III[i] + 1) / 2); if (flag >= III[i]) { IIII[i] = 2 * floor((III[i] + 1) / 2) - w1[i]; } else { IIII[i] = 2 * floor((III[i] + 1) / 2) + w1[i]; } double aa = DD * IIII[i]; double bb = EE * ((pow(IIII[i], 2)) * 0.5); G_A_NM_MODIFIED[i] = complex_sign(A_selected) * (aa + bb); } III.clear(); IIII.clear(); G_GP_REC_BEFOREMODIFY.resize(M, vector>(M, complex(0, 0))); //cout << "\n go to zhishujurec622" << endl; //zhishujurec622(G_A_NM_SELECTED, G_ZMLIST_SELECTED_10, M, oo, rr, G_GP_REC_BEFOREMODIFY); zhishujurec622(G_A_NM_SELECTED, zmlist_selected, M, oo, rr, G_GP_REC_BEFOREMODIFY); G_A_NM_SELECTED.clear(); //cout << "--------------------------" << endl; G_GP_REC.resize(M, vector>(M, complex(0, 0))); //zhishujurec622(G_A_NM_MODIFIED, G_ZMLIST_SELECTED_10, M, oo, rr, G_GP_REC); zhishujurec622(G_A_NM_MODIFIED, zmlist_selected, M, oo, rr, G_GP_REC); G_A_NM_MODIFIED.clear(); G_ZMLIST_SELECTED_10.clear(); //水印图像 for (int i = 0; i < M; i++) { for (int j = 0; j < M; j++) { Gp_watermarked[i][j] = fp(i, j) - std::real(G_GP_REC_BEFOREMODIFY[i][j]) + std::real(G_GP_REC[i][j]); } } G_GP_REC_BEFOREMODIFY.clear(); G_GP_REC_BEFOREMODIFY.clear(); G_GP_REC.clear(); cout << "rows: " << Gp_watermarked.size() << "; cols: " << Gp_watermarked[0].size() << endl; } void zhishujurec622(vector> A_nm, vector>& zmlist_selected, int M, vector> oo, vector> rr, vector>> &result) { // Initialize matrices //const int SIZE = static_cast(std::sqrt(G_L)); //int offset = 20; //if (SIZE == 32) // offset = 40; //const int COUNT_SIZE = 57; //vector count(COUNT_SIZE, 0); //vector temp_oo_row = oo[0]; //vector temp_rr_col; //vector> RBF1_col(M, complex(0.0, 0.0)); //vector> RBF2_col(M, complex(0.0, 0.0)); //// Iterate through the 32x32 grid //for (int x = 0; x < SIZE; x++) { // //start = clock(); // for (int y = 0; y < SIZE; y++) { // int row = x * SIZE + y; // int nj = zmlist_selected[row][0]; // int mc = zmlist_selected[row][1]; // complex A_nm_value = A_nm[row]; // complex conj_A_nm_value = conj(A_nm_value); // int cnt_nj = count[nj + offset]; // 32*32 +40; 10*10 +20; 16*16 +20; // double coefficient = 2 * nj * PI; // for (int i = 0; i < M; i++) // { // double rr_val = rr[i][0]; // 行相同 // double image_rr_val = coefficient * rr_val; // double cos_image_rr_val = cos(image_rr_val); // double sin_image_rr_val = sin(image_rr_val); // if (cnt_nj == 0) // { // double sqrt_part = sqrt(2.0 / rr_val); // RBF1_col[i] = sqrt_part * complex(cos_image_rr_val, sin_image_rr_val); // RBF2_col[i] = sqrt_part * complex(cos_image_rr_val, -sin_image_rr_val); // } // complex coefficient1 = A_nm_value * RBF1_col[i]; // complex coefficient2 = conj_A_nm_value * RBF2_col[i]; // for (int j = 0; j < M; j++) // { // double oo_val = temp_oo_row[j];// 列相同 // double image_rr_val = mc * oo_val; // double cos_oo_val = cos(image_rr_val); // double sin_oo_val = sin(image_rr_val); // complex front = coefficient1 * complex(cos_oo_val, sin_oo_val); // complex behind = coefficient2 * complex(cos_oo_val, -sin_oo_val); // result[i][j] += front + behind; // } // } // if (cnt_nj == 0) // { // count[nj + offset] = 1; // 32*32 +40; 10*10 +20; 16*16 +20; // } // } //} // ======================================================================================================================== // Initialize matrices const int SIZE = static_cast(std::sqrt(G_L)); int offset = 20; if (SIZE == 32) offset = 40; const int COUNT_SIZE = 57; MatrixXd eigen_oo(oo.size(), oo[0].size()); for (size_t i = 0; i < oo.size(); ++i) { for (size_t j = 0; j < oo[i].size(); ++j) { eigen_oo(i, j) = oo[i][j]; } } MatrixXcd eigen_A_nm(A_nm.size(), 1); for (size_t i = 0; i < A_nm.size(); ++i) { eigen_A_nm(i, 0) = A_nm[i]; } MatrixXd eigen_rr(rr.size(), rr[0].size()); for (size_t i = 0; i < rr.size(); ++i) { for (size_t j = 0; j < rr[i].size(); ++j) { eigen_rr(i, j) = rr[i][j]; } } VectorXi count = VectorXi::Zero(COUNT_SIZE); VectorXd temp_oo_row = eigen_oo.row(0); VectorXcd RBF1_col(M); VectorXcd RBF2_col(M); // Iterate through the 32x32 grid for (int x = 0; x < SIZE; x++) { //start = clock(); for (int y = 0; y < SIZE; y++) { int row = x * SIZE + y; int nj = zmlist_selected[row][0]; int mc = zmlist_selected[row][1]; // complex A_nm_value = A_nm[row]; complex A_nm_value = eigen_A_nm(row); complex conj_A_nm_value = conj(A_nm_value); int cnt_nj = count(nj + offset); double coefficient = 2 * nj * PI; for (int i = 0; i < M; i++) { double rr_val = eigen_rr(i, 0); double image_rr_val = coefficient * rr_val; double cos_image_rr_val = cos(image_rr_val); double sin_image_rr_val = sin(image_rr_val); if (cnt_nj == 0) { double sqrt_part = sqrt(2.0 / rr_val); RBF1_col(i) = sqrt_part * complex(cos_image_rr_val, sin_image_rr_val); RBF2_col(i) = sqrt_part * complex(cos_image_rr_val, -sin_image_rr_val); } complex coefficient1 = A_nm_value * RBF1_col[i]; complex coefficient2 = conj_A_nm_value * RBF2_col[i]; for (int j = 0; j < M; j++) { double image_rr_val = mc * temp_oo_row(j); double cos_oo_val = cos(image_rr_val); double sin_oo_val = sin(image_rr_val); complex front = coefficient1 * complex(cos_oo_val, sin_oo_val); complex behind = coefficient2 * complex(cos_oo_val, -sin_oo_val); result[i][j] += front + behind; //result[i][j] += coefficient1 * complex(cos(mc * temp_oo_row(j)), sin(mc * temp_oo_row(j))) + // coefficient2 * complex(cos(mc * temp_oo_row(j)), -sin(mc * temp_oo_row(j))); } } if (cnt_nj == 0) { count(nj + offset) = 1; } } } } // 对于复数的sign函数,返回其实部和虚部的符号组成的复数 template std::complex complex_sign(const std::complex& z) { // 处理输入为零的情况 if (z == std::complex(0, 0)) { return std::complex(0, 0); } // 计算复数的模 T magnitude = std::abs(z); // 返回归一化的复数 return std::complex(z.real() / magnitude, z.imag() / magnitude); } vector wavelet(vector BLOCK1, int level) { vector swt_output; int length = 0; swt(BLOCK1, level, "haar", swt_output, length); return swt_output; } void printSignal(vector &sig, int length = 0) { if (length == 0) length = sig.size(); for (int i = 0; i < length; i++) { cout << sig[i] << " "; } cout << endl; } double calculateMean(vector>& yo, int start, int end, int column) { double sum = 0.0; int count = 0; for (int i = start; i <= end; i++) { sum += yo[i][column]; count++; } return sum / count; } vector> general(const vector> &w, int m, int n, int a, int b) { cout << "in general" << endl; vector> f(m, vector(n, 0)); for (int x = 0; x < m; x++) { for (int y = 0; y < n; y++) { int x1 = (x + 1) + a * (y + 1); if (x1 >= m || x1 < 0) { x1 = (x1 % m + m) % m; if (x1 == 0) x1 = m; } f[x1 - 1][y] = w[x][y]; } } vector> tmp = f; for (int x = 0; x < m; x++) { for (int y = 0; y < n; y++) { int y1 = b * (x + 1) + (y + 1); if (y1 >= n || y1 < 0) { y1 = (y1 % n + n) % n; if (y1 == 0) y1 = n; } f[x][y1 - 1] = tmp[x][y]; } } return f; } vector> matToVector(const cv::Mat &ww, int rows, int cols) { vector> ww_matrix(rows, vector(cols, 0)); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (ww.at(i, j) > 0) { ww_matrix[i][j] = 1; } else { ww_matrix[i][j] = 0; } } } return ww_matrix; } void printIntSignal(vector& signal, int length = 0) { if (length == 0) length = signal.size(); for (int i = 0; i < length; i++) { cout << signal[i] << "\t"; } cout << endl; } void printMat(vector> mat) { for (std::vector sub_mat : mat) { for (double value : sub_mat) { cout << value << "\t"; } cout << endl; } cout << endl; } void printIntMat(std::vector> mat) { for (std::vector sub_mat : mat) { for (int value : sub_mat) { cout << value << " "; } cout << endl; } cout << endl; } vector readWav(drwav& wav, int& wavelength, int& channels, int& Fs) { // 使用 dr_mp3 打开 MP3 文件 //drwav wav; //if (!drwav_init_file(&wav, filename, nullptr)) { // std::cerr << "Error opening WAV file." << std::endl; // return {}; //} // 获取音频信息 channels = static_cast(wav.channels); drwav_uint64 totalPCMFrameCount = wav.totalPCMFrameCount; // 获取总 PCM 帧数 // 计算总样本数 wavelength = static_cast(totalPCMFrameCount); Fs = static_cast(wav.sampleRate); // 创建存储样本的向量 std::vector audio_f(totalPCMFrameCount * channels); std::vector audio(totalPCMFrameCount * channels); // 读取 PCM 数据 drwav_read_pcm_frames_f32(&wav, totalPCMFrameCount, audio_f.data()); // 关闭 WAV 文件 drwav_uninit(&wav); // 将 float 转换为 double for (size_t i = 0; i < totalPCMFrameCount * channels; i++) { audio[i] = static_cast(audio_f[i]); } return audio; } bool canFormSquareMatrix(const int wm_size) { if (wm_size < 0) return false; // 负数不能组成方阵 int root = static_cast(std::sqrt(wm_size)); return (root * root == wm_size); // 检查是否为完全平方数 } void getAudio20sFront(bool split, int max_wavelength, int Fs, int channels, int &wavelength, vector yo_origin, vector &yo) { if (split) { yo.reserve(max_wavelength); // 预留空间以提高性能 yo.assign(yo_origin.begin(), yo_origin.begin() + max_wavelength); wavelength = max_wavelength / channels; } else { yo = yo_origin; } } void splitAudioByTime(int max_wavelength, int Fs, int channels, int& wavelength, vector yo_origin, vector& yo, const double start_time, const double end_time, int start) { yo.resize(max_wavelength); for (int i = 0; i < max_wavelength; ++i) { yo[i] = yo_origin[start + i]; } wavelength = max_wavelength / channels; }