diff --git a/embed.cpp b/embed.cpp index 098ab38..07be44d 100644 --- a/embed.cpp +++ b/embed.cpp @@ -7,6 +7,10 @@ #include #include #include +#include +#include +#include +#include #include "global.h" #include "dr_wav.h" #include "embed.h" @@ -14,13 +18,11 @@ #include "wavelet.h" //#include "miniaudio.h" #include "dr_mp3.h" -#include -#include -#include using namespace std; using namespace cv; namespace fs = std::filesystem; +using namespace Eigen; const int k1 = 5; const double PI = 3.1416; @@ -47,7 +49,7 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const int is_mp3 = 0; int Fs = 0; int wavelength = 0; - double D = 0.8; // init 0.2 + //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; @@ -57,6 +59,7 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const fs::path fname = path; fs::path s_path = save_path; int channels; + //int bitrate; vector yo; vector yo_origin; int start = 0; @@ -83,6 +86,19 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const 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; @@ -129,11 +145,6 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const // } //} - // 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; - bool split = yo_origin.size() > max_wavelength; if (yo.empty()) { @@ -174,7 +185,8 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const } std::vector wm_vector(wm, wm + wm_size); //vector> ww_matrix = matToVector(ww, rows, cols); - vector> ww_matrix = int_ott(wm_vector, 10); + 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; @@ -185,28 +197,23 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const //block_length = rows * cols * 8 * 8; block_length = 65536; int i = 1; - int left = i * (Lsyn * k1 + block_length); + //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) * 2)) + 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; - + //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]) @@ -224,36 +231,33 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const } 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> 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++) { @@ -261,11 +265,10 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const 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)); + 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++) { @@ -273,7 +276,6 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const uu[k][j] = k + 1; } } - // 计算 rr 和 oo 矩阵 for (int k = 0; k < M; k++) { for (int j = 0; j < M; j++) { @@ -340,7 +342,7 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const cout << "==============================================================" << endl; i++; - left = i * (Lsyn * k1 + block_length); + //left = i * (Lsyn * k1 + block_length); } cout << "t0:" << endl; printIntSignal(t0, 0); @@ -373,6 +375,8 @@ int wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, const 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); @@ -412,35 +416,54 @@ vector inverseWavelet(vector swt_output, int level) { return iswt_output; } -void PQIMfft_embed(vector> &Gp, vector>& fp, +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; - zhishujufenjie62(Gp, M, G_NMAX_10, G_A_NM_10, G_ZMLIST_10); + 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(G_ZMLIST_10.size(), 0); - vector index_m(G_ZMLIST_10.size(), 0); + vector index_n(zmlist.size(), 0); + vector index_m(zmlist.size(), 0); - for (int i = 0; i < G_ZMLIST_10.size(); i++) { - index_n[i] = G_ZMLIST_10[i][0]; - index_m[i] = G_ZMLIST_10[i][1]; + 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 < G_ZMLIST_10.size(); i++) { - // 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); + 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); + } } - // 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(); @@ -450,13 +473,14 @@ void PQIMfft_embed(vector> &Gp, vector>& fp, index_suitable.clear(); // 得到在zmlist中的对应的数据,为下一步重构准备的 - G_ZMLIST_SELECTED_10.resize(G_L, vector(2, 0)); - + //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]]; - G_A_NM_SELECTED[i] = G_A_NM_10[index_selected_embed[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(); @@ -495,7 +519,8 @@ void PQIMfft_embed(vector> &Gp, vector>& fp, //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, 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(); @@ -503,14 +528,15 @@ void PQIMfft_embed(vector> &Gp, vector>& fp, 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, 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]); + Gp_watermarked[i][j] = fp(i, j) - std::real(G_GP_REC_BEFOREMODIFY[i][j]) + std::real(G_GP_REC[i][j]); } } @@ -524,13 +550,88 @@ void PQIMfft_embed(vector> &Gp, vector>& fp, void zhishujurec622(vector> A_nm, vector>& zmlist_selected, int M, vector> oo, vector> rr, vector>> &result) { // Initialize matrices - const int SIZE = 10; - const int COUNT_SIZE = 57; - vector count(COUNT_SIZE, 0); - vector temp_oo_row = oo[0]; + //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)); + //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(); @@ -538,27 +639,28 @@ void zhishujurec622(vector> A_nm, vector>& zmlist_se 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 = 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 + 20]; // 32*32 +40; 10*10 +20; 16*16 +20; + int cnt_nj = count(nj + offset); double coefficient = 2 * nj * PI; for (int i = 0; i < M; i++) { - double rr_val = rr[i][0]; // 行相同 + 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); + 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 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); @@ -569,78 +671,10 @@ void zhishujurec622(vector> A_nm, vector>& zmlist_se } if (cnt_nj == 0) { - count[nj + 20] = 1; // 32*32 +40; 10*10 +20; 16*16 +20; + count(nj + offset) = 1; } } } - - // ======================================================================================================================== - //// 创建Eigen矩阵 - //MatrixXcd RBF1(M, M); - //MatrixXcd RBF2(M, M); - //MatrixXcd P_NM1(M, M); - //MatrixXcd P_NM2(M, M); - //// 填充RBF矩阵 - //RBF1.setZero(); - //RBF2.setZero(); - //for (int i = 0; i < M; i++) { - // for (int j = 0; j < M; j++) { - // double r = rr[i][j]; - // double theta = oo[i][j]; - // RBF(i, j) = sqrt(2.0 / r) * exp(complex(0, theta)); - // } - //} - //// 填充P_NM矩阵 - //P_NM1.setZero(); - //P_NM2.setZero(); - //for (size_t k = 0; k < zmlist_selected.size(); k++) { - // int n = zmlist_selected[k][0]; - // int m = zmlist_selected[k][1]; - // complex a_nm = A_nm[k]; - // for (int i = 0; i < M; i++) { - // for (int j = 0; j < M; j++) { - // double r = rr[i][j]; - // P_NM(i, j) += a_nm * pow(r, abs(n)) * exp(complex(0, m * oo[i][j])); - // } - // } - //} - //// 执行矩阵乘法 - //MatrixXcd Result = RBF.cwiseProduct(P_NM); - //// 将结果转换回vector>>格式 - //for (int i = 0; i < M; i++) { - // for (int j = 0; j < M; j++) { - // result[i][j] = Result(i, j); - // } - //} - //for (int x = 0; x < SIZE; x++) { - // for (int y = 0; y < SIZE; y++) { - // int row = x * SIZE + y; - // int nj = zmlist_selected[row][0]; - // int mc = zmlist_selected[row][1]; - // int cnt_nj = count[nj + 40]; - // if (cnt_nj == 0) - // { - // for (int i = 0; i < M; i++) { - // for (int j = 0; j < M; j++) { - // double r = rr[i][j]; - // double theta = 2 * nj * PI * r; - // RBF1(i, j) = sqrt(2.0 / r) * exp(complex(0, theta)); - // RBF2(i, j) = sqrt(2.0 / r) * exp(complex(0, -theta)); - // } - // } - // } - // for (int i = 0; i < M; i++) { - // for (int j = 0; j < M; j++) { - // double o = oo[i][j]; - // double image_part = mc * o; - // P_NM1(i, j) = RBF1(i, j) * exp(complex(0, image_part)); - // P_NM2(i, j) = RBF2(i, j) * exp(complex(0, -image_part)); - // A_nm[row] * P_NM1(i, j) + P_NM2(i, j); - // } - // } - // } - //} - //cout << "zhishujurec622 finsh" << endl; } // 对于复数的sign函数,返回其实部和虚部的符号组成的复数 diff --git a/embed.h b/embed.h index a01666f..bc7a5cf 100644 --- a/embed.h +++ b/embed.h @@ -9,12 +9,14 @@ #include #include #include +#include #include "global.h" #include "dr_wav.h" using namespace std; using namespace cv; namespace fs = std::filesystem; +using namespace Eigen; vector> general(const vector>& w, int m, int n, int a, int b); @@ -22,7 +24,8 @@ std::vector> matToVector(const cv::Mat& ww, int rows, int cols) void printSignal(vector &signal, int length); -void PQIMfft_embed(vector> &Gp, vector> &fp, vector &w1, int M, double DD, double EE, vector> &oo, vector> &rr, vector> &Gp_watermarked); +//void PQIMfft_embed(vector> &Gp, vector> &fp, vector &w1, int M, double DD, double EE, vector> &oo, vector> &rr, vector> &Gp_watermarked); +void PQIMfft_embed(MatrixXd Gp, MatrixXd fp, vector& w1, int M, double DD, double EE, vector>& oo, vector>& rr, vector>& Gp_watermarked); void saveAudio(const char* outputFilename, std::vector& yo, int sampleRate, int channels); // 对于复数的sign函数,返回其实部和虚部的符号组成的复数 diff --git a/extract.cpp b/extract.cpp index 83f90df..0f768b2 100644 --- a/extract.cpp +++ b/extract.cpp @@ -1,6 +1,7 @@ #include "extract.h" #include "util.h" #include "embed.h" +#include "global.h" #include #include #include @@ -18,7 +19,7 @@ using namespace std; using namespace cv; namespace fs = std::filesystem; -int wm_extract(const wchar_t *path, int *wm) +int wm_extract(const wchar_t *path, int *wm, int wm_size) { fs::path fname = path; vector yw; @@ -26,8 +27,9 @@ int wm_extract(const wchar_t *path, int *wm) int wavelength; int Fs; int numChannels; + //int bitrate; string extract_path = ConvertUTF16ToMBCS(path); - + if (isMp3File(fname, extract_path)) { // is mp3 @@ -36,13 +38,11 @@ int wm_extract(const wchar_t *path, int *wm) Fs = (int)Fs_long; } else { - //drwav wav; drwav wav; if (!drwav_init_file(&wav, extract_path.c_str(), nullptr)) { std::cerr << "Error opening WAV file." << std::endl; return 1; } - yw = readWav(wav, wavelength, numChannels, Fs); } @@ -72,14 +72,14 @@ int wm_extract(const wchar_t *path, int *wm) vector synw = syn; vector temp1 = syn; int Lsyn = syn.size(); - int pp = 10; - int qq = 10; + int pp = static_cast(std::sqrt(wm_size)); + int qq = static_cast(std::sqrt(wm_size)); vector b; vector> W1(pp, vector(qq, 0)); int k1 = 5; double PI = 3.1416; - double D = 0.8; + //double D = 0.8; double DD = 0.0012; double EE = 0.00002; //int blocklength = pp * qq * 8 * 8; // 32x32 ˮӡ��С @@ -91,8 +91,8 @@ int wm_extract(const wchar_t *path, int *wm) cout << "wavelength: " << wavelength << endl; - while (k + (i * Lsyn * k1) < wavelength) { - while (rela != 0 && (k + Lsyn * k1) < wavelength) { + while (k + (i * Lsyn * k1) < wavelength - (Lsyn * k1 + blocklength)) { + while (rela != 0 && (k + Lsyn * k1) < wavelength - (Lsyn * k1 + blocklength)) { for (int mm = 0; mm < Lsyn; mm++) { double tempmean = 0.0; @@ -124,10 +124,10 @@ int wm_extract(const wchar_t *path, int *wm) vector bt_temp; vector> bt; vector t1; - cout << "t0:" << endl; + cout << "t0: (size = " << t0.size() << ")" << endl; printIntSignal(t0, 0); - for (int ii = 0; ii < i - 3; ii++) { - t1.push_back(t0[ii] + Lsyn * k1); + for (int ii = 0; ii < t0.size(); ii++) { + t1.push_back(t0[ii] + Lsyn * k1 + 1); if (t1[ii] + blocklength - 1 > wavelength) { W1 = vector>(pp, vector(qq, 1)); } @@ -151,7 +151,8 @@ int wm_extract(const wchar_t *path, int *wm) int M = 4 * n; - vector> Gp_w(M, vector(M, 0.0)); + //vector> Gp_w(M, vector(M, 0.0)); + MatrixXd Gp_w(M, M); for (int u = 0; u < M; u++) { for (int v = 0; v < M; v++) { @@ -163,20 +164,19 @@ int wm_extract(const wchar_t *path, int *wm) int row = -kk + (n / 2); int col = ll + (n / 2) - 1; - Gp_w[u][v] = (I_w1[row][col]) * sqrt(static_cast(u) / (2 * M)); + Gp_w(u, v) = (I_w1[row][col]) * sqrt(static_cast(u) / (2 * M)); } } - - bt_temp = PQIMfft_extract(Gp_w, b, M, DD, EE); + bt_temp = PQIMfft_extract(Gp_w, b, M, DD, EE, pp); bt.push_back(bt_temp); } } - cout << "t1:" << endl; + cout << "t1: (size = " << t1.size() << ")" << endl; printIntSignal(t1, t1.size()); // watermark capacity 32*32=1024 16*16=256 10*10=100 - vector r(100); - for (int iii = 0; iii < 100; iii++) { + vector r(wm_size); + for (int iii = 0; iii < wm_size; iii++) { double sum_bt = 0.0; // ���� bt ���к� @@ -185,25 +185,26 @@ int wm_extract(const wchar_t *path, int *wm) } // ���� r(iii) - r[iii] = static_cast(round(sum_bt / (bt.size() - 1))); + //r[iii] = static_cast(round(sum_bt / 15)) >= 1 ? 1 : 0; + r[iii] = static_cast(round(sum_bt / t1.size())) >= 1 ? 1 : 0; } - for (size_t i = 0; i < r.size(); ++i) { - wm[i] = r[i]; - } + //for (size_t i = 0; i < r.size(); ++i) { + // wm[i] = r[i]; + //} - W1 = int_ott(r, 10); + W1 = int_ott(r, pp); vector> W2 = igeneral(W1, pp, qq, 5, 6); - cout << "\n W1:" << endl; - printIntMat(W1); + //cout << "\n W1:" << endl; + //printIntMat(W1); cout << "\n W2:" << endl; printIntMat(W2); //cout << "\n W:" << endl; //printIntMat(W); - vector wm_vec = int_tto(W2, 10); + vector wm_vec = int_tto(W2, pp); //wm = new int[wm_vec.size()]; @@ -216,85 +217,63 @@ int wm_extract(const wchar_t *path, int *wm) return 0; // todo: ͼ�񱣴� - //string fname_origin = "D://wm_project/audio/female.mp3"; ////��ȡ��Ƶ�ļ� //SNDFILE* sndFile_origin; //SF_INFO sfInfo_origin{}; //sfInfo_origin.format = 0; - //sndFile_origin = sf_open(fname_origin.c_str(), SFM_READ, &sfInfo_origin); - //if (!sndFile_origin) { // cerr << "Error opening audio file." << endl; //} - //int origin_numChannels = sfInfo_origin.channels; - //vector yo; - //yo.resize(sfInfo_origin.frames * origin_numChannels); - //sf_read_double(sndFile_origin, yo.data(), sfInfo_origin.frames * numChannels); - //sf_close(sndFile_origin); - //double psnr = psnrzh(yw, yo); - //cout << "psnr:" << psnr << endl; - //double wsr = getWsr(yw, yo); - //cout << "wsr:" << wsr << endl; } -vector PQIMfft_extract(vector>& Gp_w, vector& b, int M, double DD, double EE) +vector PQIMfft_extract(MatrixXd Gp_w, vector& b, int M, double DD, double EE, int pp) { - //const vector key1 = { 0.928193675245596, 0.762097922072739, 0.380267928722993, 0.897730320468743, 0.100822133636870, 0.0899504433067866, 0.239020109274386, - //0.946779913782277, 0.0952670768819904, 0.320156919270540, 0.577931144724556, 0.196373121839455, 0.461274061204655, 0.323929634780567, 0.807739985547207, 0.540754730983380, - //0.985142082650825, 0.958345377953601, 0.185229603238548, 0.0660488670603961, 0.00835748882788212, 0.433219741512797, 0.501328268578626, 0.684454533009209, 0.0274337980435039, - //0.821913355398633, 0.758935114048920, 0.612561055737784, 0.223044160578087, 0.578077449230608, 0.287499282769805, 0.965226733423526, 1.11022302462516e-16, 0, 2.55749847299924e-07 }; - - //const vector key2 = { 0.164635665117893, 0.758726063009854, 0.00591829393010890, 0.964050036774166, 0.984922993786984, 0.976826357531615, 0.356700569394344, - //0.203547152614262, 0.336560412745046, 0.498445989825352, 0.997342009306155, 0.749864280396276, 0.470142180541784, 0.874301822643799, 0.0868517482511835, 0.895214310591549, - //0.583643833047015, 0.694493484576109, 0.884424240366055, 0.919066545678925, 0.790112074974144, 0.647724940400028, 0.363864662192446, 0.879399867540293, 0.249724426967429, - //0.134744306769869, 0.248274963641751, 0.0776257270260381, 0.143523293499973, 0.263989850166916, 0.892556319897704, 0.333508113443291, 1.11022302462516e-16, 3.33066907387547e-15, - //4.52511162984948e-07 }; - //int L = b.size(); - int L = 100; - - const int Nmax = 20; - const int size = 2 * Nmax + 1; - const int total_elements_32 = size * size; + int L = pp * pp; + int Nmax = 20; + if (pp == 32) + Nmax = 40; + int size = 2 * Nmax + 1; + int total_elements_32 = size * size; vector> A_nm(total_elements_32, (0, 0)); vector> zmlist(total_elements_32, vector(2, 0)); - // ָ���صķֽ� + zhishujufenjie62(Gp_w, M, Nmax, A_nm, zmlist); vector index_selected_extract(L); - // ����������� vector index_suitable; - vector> A_nm_selected_extract(L, 0.0); - vector b_extract(L, 0.0); for (int i = 0; i < zmlist.size(); i++) { int index_n_temp = zmlist[i][0]; int index_m_temp = zmlist[i][1]; - - // 10*10/16*16 embed range - if (((index_m_temp == 0) && (index_n_temp < 0)) || - ((index_m_temp > 0) && (index_m_temp <= 10) && (-4 <= index_n_temp) && (index_n_temp <= 4))) { - index_suitable.push_back(i); + if (pp == 32) { + // 32*32 embed range + if (((index_m_temp == 0) && (index_n_temp < 0)) || + ((index_m_temp > 0) && (index_m_temp <= 30) && (-16 <= index_n_temp) && (index_n_temp <= 16))) { + index_suitable.push_back(i); + } + } + else { + // 10*10/16*16 embed range + if (((index_m_temp == 0) && (index_n_temp < 0)) || + ((index_m_temp > 0) && (index_m_temp <= 10) && (-4 <= index_n_temp) && (index_n_temp <= 4))) { + index_suitable.push_back(i); + } } - // 32*32 embed range - /*if (((index_m_temp == 0) && (index_n_temp < 0)) || - ((index_m_temp > 0) && (index_m_temp <= 30) && (-16 <= index_n_temp) && (index_n_temp <= 16))) { - index_suitable.push_back(i); - }*/ } for (int i = 0; i < L; i++) diff --git a/extract.h b/extract.h index 5a06764..2d16bee 100644 --- a/extract.h +++ b/extract.h @@ -11,12 +11,14 @@ #include #include #include +#include using namespace std; +using namespace Eigen; -int wm_extract(const wchar_t* path, int* wm); +int wm_extract(const wchar_t* path, int* wm, int wm_size); -vector PQIMfft_extract(vector> &Gp_w, vector &b, int M, double DD, double EE); +vector PQIMfft_extract(MatrixXd Gp_w, vector &b, int M, double DD, double EE, int pp); double drzh(const vector>& ww, vector>& W1, int pp, int qq); diff --git a/global.cpp b/global.cpp index bfe061b..f03ada6 100644 --- a/global.cpp +++ b/global.cpp @@ -4,6 +4,8 @@ double g_audio_wm_progress = 0; double Delta = 0.0008; +double D = 0.8; + double standard_avg_amplitude = 0.066535893026576018; double standard_amplitude_sum = 146711.64412360013; \ No newline at end of file diff --git a/global.h b/global.h index 9019419..526dc9b 100644 --- a/global.h +++ b/global.h @@ -2,5 +2,6 @@ extern double g_audio_wm_progress; extern double Delta; +extern double D; extern double standard_avg_amplitude; extern double standard_amplitude_sum; \ No newline at end of file diff --git a/main.cpp b/main.cpp index 57cdc1f..8cc0686 100644 --- a/main.cpp +++ b/main.cpp @@ -9,16 +9,46 @@ #include "Log.h" #include "new_embed.h" #include "new_extract.h" +#include +#include +#include +#include + +namespace fs = std::filesystem; int main(){ //Log audio_logger; fmt::println("welcome to use audio watermark system"); //audio_logger.log(); //const wchar_t* path = L"D://音频/female.mp3"; - const wchar_t* path = L"D:/temp/apple.wav"; - const wchar_t* save_path = L"D:/temp/apple_wm.wav"; - wstring s_path = AddSuffixToPath(path, L"_resample"); - wcout << s_path << endl; + const wchar_t* path = L"D:/resource/error_file/output_002.mp3"; + const wchar_t* save_path = L"D:/resource/output_002_wm.mp3"; + const int wm[1024]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + //const int wm[100] = {0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,1,0,1,0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,1,0,0,0,1,1,0,0,1,0,1,0,0,1,1,0,1,1,1,0,1,1,1,0,0,0,1,1,0,1,1,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,0,1,1,0,1}; + //wstring s_path = AddSuffixToPath(path, L"_resample"); + //wcout << s_path << endl; //convert_wav(path, s_path.c_str()); //fs::path fname = s_path; //std::filesystem::remove(fname); @@ -37,89 +67,55 @@ int main(){ clock_t start = 0, end = 0; double totaltime = 0.0; start = clock(); - //const int wm[1024]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, - // 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, - // 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, - // 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - // 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, - // 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, - // 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - // 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - const int wm[100] = {0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,1,0,1,0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,1,0,0,0,1,1,0,0,1,0,1,0,0,1,1,0,1,1,1,0,1,1,1,0,0,0,1,1,0,1,1,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,0,1,1,0,1}; - wm_embed(path, save_path, wm, 100, 0, 75); + wm_embed(path, save_path, wm, 1024, 0, 25); //char* wm = "0000000000000000000000000000000000000000000000110000000000000000000000000000011100000000000000000000"; //char* wm = "0000000100000000000000110000000000000010001100000001001111110000000110111111100000001111111110000000"; - //new_wm_embed(path, save_path, wm, 100, 0, 30); + //new_wm_embed(path, save_path, wm, 100, 0, 25); end = clock(); totaltime = (double)(end - start) / CLOCKS_PER_SEC; cout << "耗时: " << totaltime << endl; } else { - const wchar_t* extract_path = L"D:/音频/苹果眼镜_wm.wav"; - int* wm = new int[100]; + //const wchar_t* extract_path = L"D:/temp/apple_wm.wav"; + int* ex_wm = new int[1024]; //char* wm = new char[100]; //D://wm_audio/news_wm_release.wav - int code = wm_extract(save_path, wm); + int code = wm_extract(save_path, ex_wm, 1024); //int code = new_wm_extract(save_path, wm); + int ber = 0; + vector tm; + for (int i = 0; i < 1024; i++) { + if (wm[i] != ex_wm[i]) { + tm.push_back(i); + ber++; + } + } + cout << "be = " << ber << "; ber = " << static_cast(ber) / 1024 * 100 << endl; + for (auto item : tm) { + cout << item << "\t"; + } } - return 0; } -// 线程函数 -//void embedWatermark() -//{ -// // 调用 wm_embed 函数 -// clock_t start = 0, end = 0; -// double totaltime = 0.0; -// start = clock(); -// const int wm[1024]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, -// 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, -// 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, -// 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, -// 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -// 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, -// 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -// int result = wm_embed("D://wm_project/audio/female.mp3", "D://wm_audio", wm, 100); -// end = clock(); -// totaltime = (double)(end - start) / CLOCKS_PER_SEC; -// cout << "总耗时: " << totaltime << endl; -// -// // 假设 wm_embed 函数内部会更新 g_audio_wm_progress -// if (result == 0) { -// std::cout << "水印嵌入成功" << std::endl; -// } else { -// std::cout << "水印嵌入失败,错误代码:" << result << std::endl; + + +//int main() { +// string filePath = "D:/FFOutput/Souleymane.wav"; +// // 声明输出文件名格式 +// std::string outputFormat = "D:/FFOutput/Souleymane_%03d.wav"; // 输出文件名格式 +// +// // 使用 ffmpeg 拆分音频的命令 +// std::string command = "ffmpeg -i \"" + filePath + "\" -f segment -segment_time 30 -c copy \"" + outputFormat + "\""; +// +// // 执行命令 +// int result = std::system(command.c_str()); +// +// // 检查执行结果 +// if (result != 0) { +// std::cerr << "Error: Unable to split audio file." << std::endl; +// } +// else { +// std::cout << "Audio file split into segments successfully." << std::endl; // } //} \ No newline at end of file diff --git a/new_embed.cpp b/new_embed.cpp index 8d2c45b..a20c9d3 100644 --- a/new_embed.cpp +++ b/new_embed.cpp @@ -26,9 +26,11 @@ int new_wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, c int Fs = 0; int start = -1; int wavelength = 0; - vector syn = { 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0 }; - const int Lsyn = syn.size(); + //vector syn = { 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0 }; + vector syn = { 1, 1, 1, 1, 1, 0, 0, 1 }; + const int Lsyn = 2 * syn.size(); int channels; + //int bitrate; vector yo; vector yo_origin; fs::path fname = path; @@ -53,6 +55,12 @@ int new_wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, c yo_origin = readWav(wav, wavelength, channels, Fs); } + 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; if ((end_time - start_time) < 25.0) @@ -98,7 +106,7 @@ int new_wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, c // stage 2 - preparation work for watermark std::vector wm_vector(wm, wm + wm_size); - //// 输出结果 + // 输出结果 std::cout << "wm_vector: "; for (int value : wm_vector) { std::cout << value << " "; @@ -115,14 +123,15 @@ int new_wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, c vector w1 = int_tto(w, rows); // stage 3 - params init - double D = 1; + //double D = 0.8; //double Delta = 0.0008; - int k1 = 5; - int begin = 4095; - int block_length = 65536; - int i = 1; - int left = i * (Lsyn * k1 + block_length); - int right = wavelength - (Lsyn * k1 + block_length); + int k1 = 5; + int begin = 4095; + int block_length = 65536; + int i = 1; + //int left = i * (Lsyn * k1 + block_length); + int right = wavelength - (Lsyn * k1 + block_length); + int barkcode_length = k1 * syn.size(); vector t0; // stage 4 - start embed @@ -132,13 +141,13 @@ int new_wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, c int bb = begin + (i - 1) * (Lsyn * k1 + block_length); // embed syn code cout << "embed syn code at index: " << bb << endl; - for (int mm = 0; mm < Lsyn; mm++) + for (int mm = 0; mm < syn.size(); mm++) { vector temp_vec_subsyn; - int front = bb + (mm * k1); + int front = bb + (mm * k1) + 1; int back = bb + ((mm + 1) * k1); // calculate mean value - double tempmean = calculateMean(audio_data, front + 1, back, 0); // front = 4096 back = 4100 + double tempmean = calculateMean(audio_data, front, back, 0); // front = 4096 back = 4100 int temp = static_cast(round(tempmean / D)); double tempmeanl; if (((temp) % 2 + 2) % 2 == syn[mm]) @@ -152,6 +161,7 @@ int new_wm_embed(const wchar_t* path, const wchar_t* save_path, const int* wm, c for (int j = front; j <= back; j++) { audio_data[j][0] += tempmeanl - tempmean; + audio_data[j + barkcode_length][0] = audio_data[j][0]; } } diff --git a/new_extract.cpp b/new_extract.cpp index b53e0f4..83e1354 100644 --- a/new_extract.cpp +++ b/new_extract.cpp @@ -30,6 +30,7 @@ int new_wm_extract(const wchar_t* path, int* wm) int wavelength; int Fs; int numChannels; + //int bitrate; string extract_path = ConvertUTF16ToMBCS(path); if (isMp3File(fname, extract_path)) { @@ -65,10 +66,11 @@ int new_wm_extract(const wchar_t* path, int* wm) } } - vector syn = { 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0 }; + //vector syn = { 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0 }; + vector syn = { 1, 1, 1, 1, 1, 0, 0, 1 }; vector synw = syn; vector temp1 = syn; - int Lsyn = syn.size(); + int Lsyn = 2 * syn.size(); int pp = 10; int qq = 10; vector b; @@ -77,13 +79,14 @@ int new_wm_extract(const wchar_t* path, int* wm) cout << "stage 2 - params init" << endl; int k1 = 5; double PI = 3.1416; - double D = 1; + //double D = 1; //double Delta = 0.0008; //int blocklength = pp * qq * 8 * 8; // wm size 32*32 int blocklength = 65536; int k = 0; int i = 1; int rela = 1; + int barkcode_length = k1 * syn.size(); vector t0; cout << "wavelength: " << wavelength << endl; // stage 3 - position syn code @@ -92,29 +95,46 @@ int new_wm_extract(const wchar_t* path, int* wm) { while (rela != 0 && (k + Lsyn * k1) < wavelength) { - for (int mm = 0; mm < Lsyn; mm++) { + for (int mm = 0; mm < syn.size(); mm++) { double tempmean = 0.0; - int front = k + mm * k1; - int back = k + (mm + 1) * k1 - 1; + int front = k + mm * k1 + 1; + int back = k + (mm + 1) * k1; tempmean = calculateMean(audio_data, front, back, 0); int temp = floor(tempmean / D); synw[mm] = (temp % 2 + 2) % 2; temp1[mm] = syn[mm] ^ synw[mm]; } - rela = accumulate(temp1.begin(), temp1.end(), 0); + //rela = accumulate(temp1.begin(), temp1.end(), 0); + if (accumulate(temp1.begin(), temp1.end(), 0) == 0) { + cout <<"found syn in "<< k << endl; + vector barkcode_fornt10 = vector(yw.begin() + k + 10, yw.begin() + k + 20); + vector barkcode_copy = vector(yw.begin() + k + barkcode_length, yw.begin() + k + 2 * barkcode_length); + for (int j = 0; j < barkcode_copy.size() - barkcode_fornt10.size(); j++) { + if (allEqual(vector(barkcode_copy.begin() + j, barkcode_copy.begin() + j + barkcode_fornt10.size()), barkcode_fornt10)) { + t0.push_back(k - 1); + k = k + (Lsyn * k1) + blocklength - 1; + //t0[i] = k - 1; + i++; + rela = 0; + break; + } + } + } k++; } - t0.push_back(k - 1); + //t0.push_back(k - 1); + if (t0.size() >= 15) + break; rela = 1; - k = k + (Lsyn * k1) + blocklength - 1; - i++; + //i++; + /*k = k + (Lsyn * k1) + blocklength - 1;*/ } printIntSignal(t0, 0); cout << "\nstage 4 - watermark extract" << endl; vector bt_temp; vector> bt; vector t1; - for (int ii = 0; ii < i - 1; ii++) + for (int ii = 0; ii < t0.size(); ii++) { cout << "extract watermark current batch No." << ii + 1 << endl; int t1_item = t0[ii] + Lsyn * k1 + 1; diff --git a/util.cpp b/util.cpp index 6c7a994..d2f5969 100644 --- a/util.cpp +++ b/util.cpp @@ -168,9 +168,10 @@ void fft2(Mat& input, Mat& output, bool invert = false, bool normalize = false) //} } -void zhishujufenjie62(vector>& Gp, int M, int Nmax, vector>& A_nm, vector>& zmlist) { - int rows = Gp.size(); - int cols = Gp[0].size(); +void zhishujufenjie62(MatrixXd Gp, int M, int Nmax, vector>& A_nm, vector>& zmlist) { + //int rows = Gp.size(); + int rows = static_cast(sqrt(Gp.size())); + int cols = rows; const int size = 2 * Nmax + 1; // Allocate FFTW complex arrays fftw_complex* in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * rows * cols); @@ -178,7 +179,7 @@ void zhishujufenjie62(vector>& Gp, int M, int Nmax, vector>& Gp, int M, int Nmax, vector>> Gp_fft(rows, vector>(cols, complex(0, 0))); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { - Gp_fft[i][j] = complex(out[i * cols + j][0], in[i * cols + j][1]); + //Gp_fft[i][j] = complex(out[i * cols + j][0], in[i * cols + j][1]); + Gp_fft[i][j] = complex(out[i * cols + j][0], out[i * cols + j][1]); } } // Cleanup @@ -291,11 +293,13 @@ void save_audio_drmp3(const wchar_t* outputFilename, vector& yo, int sam lame_set_in_samplerate(lame, sampleRate); lame_set_num_channels(lame, channels); lame_set_out_samplerate(lame, sampleRate); + //lame_set_brate(lame, bitrate); lame_set_quality(lame, 5); // 0-9, 5是中等质量 lame_init_params(lame); // 打开输出文件 - FILE* mp3File = _wfopen(outputFilename, L"wb"); + FILE* mp3File = nullptr; + errno_t err = _wfopen_s(&mp3File, outputFilename, L"wb"); if (!mp3File) { std::cerr << "cann't open file: " << outputFilename << std::endl; lame_close(lame); @@ -370,6 +374,10 @@ vector mp3ToDoubleVector(const char* mp3File, int &channels, long &rate, mpg123_getformat(mh, &rate, &channels, &encoding); + // 获取比特率 + //mpg123_frameinfo2 id3v2; + //mpg123_info2(mh, &id3v2); + //bitrate = id3v2.bitrate; std::vector audioData; unsigned char buffer[4096]; size_t done; @@ -576,4 +584,14 @@ wstring string_to_wstring(const std::string& str) { std::wstring wstr(size_needed, 0); MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), &wstr[0], size_needed); return wstr; +} + +bool allEqual(const vector& vec1, const vector& vec2) { + if (vec1.size() != vec2.size()) + return false; + for (size_t i = 0; i < vec1.size(); i++) { + if (vec1[i] != vec2[i]) + return false; + } + return true; } \ No newline at end of file diff --git a/util.h b/util.h index dc668ee..945402a 100644 --- a/util.h +++ b/util.h @@ -6,10 +6,12 @@ #include #include #include +#include using namespace std; using namespace cv; namespace fs = std::filesystem; +using namespace Eigen; struct WAVHeader { @@ -48,7 +50,7 @@ void fft1d(vector>& data, bool invert); void fft2(Mat& input, Mat& output, bool invert, bool normalize); -void zhishujufenjie62(std::vector> &Gp, int M, int Nmax, vector> &A_nm, vector> &zmlist); +void zhishujufenjie62(MatrixXd Gp, int M, int Nmax, vector> &A_nm, vector> &zmlist); //void printMessage(vector &msg); @@ -82,4 +84,6 @@ void resample(const float* inputBuffer, size_t inputSize, float* outputBuffer, s void convert_wav(vector& inputBuffer, int& inputRate, int channels, const wchar_t* outputPath); -wstring AddSuffixToPath(const wchar_t* originalPath, const wstring& suffix); \ No newline at end of file +wstring AddSuffixToPath(const wchar_t* originalPath, const wstring& suffix); + +bool allEqual(const vector& vec1, const vector& vec2); \ No newline at end of file