我有一個需求,我需要多次寫入wav(與pcma數據)文件。Wav文件寫入和播放多重時間
說我有一個文件audio-g711a.wav。我想寫它到一個新的文件說audio-g711a-out.wav 2次。當我播放audio-g711a-out.wav時,它應該播放比原始文件長兩倍的播放時間。
我用下面的代碼寫了。但是它的播放時間與原始文件的播放時間完全相同(我期待它能播放兩倍的時間)。
代碼如下。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int g_count = 0;
void init_config(int argc,char **argv);
void rewrite_file(int count);
int main(int argc, char **argv)
{
init_config(argc, argv);
printf("Count = %d\n", g_count);
rewrite_file(g_count);
return 0;
}
void rewrite_file(int count)
{
int index;
char arr[101];
FILE *fd_in;
FILE *fd_out;
size_t len;
unsigned long chunk_size;
index = 0;
fd_in = fopen("./audio-g711a.wav", "r");
fd_out = fopen("./audio-g711a-out.wav", "w+");
rw_again:
index++;
len = fread(arr, 1, 100, fd_in);
while(len == 100)
{
fwrite(arr, 1, 100, fd_out);
len = fread(arr, 1, 100, fd_in);
}
fwrite(arr, 1, len, fd_out);
if(count > index)
{
printf("Completed %d round of operation of %d total rounds.\n", index, count);
fclose(fd_in);
fd_in = fopen("./audio-g711a.wav", "r");
goto rw_again;
}
return;
}
void init_config(int argc,char **argv)
{
int ch;
while ((ch = getopt(argc, argv, "v:n:N:X")) != -1)
{
switch (ch)
{
case 'n':
case 'N':
{
g_count = atoi(optarg);
}
break;
default:
break;
}
}
return;
}
要執行此操作,一個可以執行像./a.out -n 2
一些ř& d後,我意識到wav文件有某種報頭。當我第二次寫作時,我再次寫頭。這可能會導致文件無法進一步播放。在第二次寫入時,我停止寫頭部分(44字節)。這並沒有解決問題。
有人可以請指導我怎樣才能實現至少2次寫入wav文件。
更新
工作代碼如下。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int g_count = 0;
void init_config(int argc,char **argv);
void rewrite_file(int count);
int main(int argc, char **argv)
{
init_config(argc, argv);
printf("Count = %d\n", g_count);
rewrite_file(g_count);
return 0;
}
void rewrite_file(int count)
{
int index;
char arr[101];
FILE *fd_in;
FILE *fd_out;
size_t len;
unsigned short data_index = 0;
index = 0;
fd_in = fopen("./audio-g711a.wav", "r");
fd_out = fopen("./audio-g711a-out.wav", "w+");
// copy header
len = fread(arr, 1, 40, fd_in);
fwrite(arr, 1, len, fd_out);
if(strncmp("data", (arr+36), 4) == 0)
{
data_index = 40;
}
else
{
len = fread(arr, 1, 14, fd_in);
fwrite(arr, 1, len, fd_out);
if(strncmp("data", (arr+10), 4) == 0)
{
data_index = 54;
}
}
// update header
uint32_t dl;
fseek(fd_in, data_index, SEEK_SET);
fseek(fd_out, data_index, SEEK_SET);
fread(&dl, sizeof(dl), 1, fd_in);
dl *= count;
fwrite(&dl, sizeof(dl), 1, fd_out);
// copy data
rw_again:
index++;
fseek(fd_in, (4 + data_index), SEEK_SET);
len = fread(arr, 1, 100, fd_in);
while(len > 0)
{
fwrite(arr, 1, len, fd_out);
len = fread(arr, 1, 100, fd_in);
}
fwrite(arr, 1, len, fd_out);
if(count > index)
{
printf("Completed %d round of operation of %d total rounds.\n", index, count);
fclose(fd_in);
fd_in = fopen("./audio-g711a.wav", "r");
goto rw_again;
}
fclose(fd_in);
fclose(fd_out);
return;
}
void init_config(int argc,char **argv)
{
int ch;
while ((ch = getopt(argc, argv, "v:n:N:X")) != -1)
{
switch (ch)
{
case 'n':
case 'N':
{
g_count = atoi(optarg);
}
break;
default:
break;
}
}
return;
}
查找標題的格式。您需要更改標題的某些部分。 – immibis
我看到了這裏的格式http://www.codeproject.com/Articles/29676/CWave-A-Simple-C-Class-to-Manipulate-WAV-Files。但不明白我需要做什麼... – Kamal
標題只有36個字節。以下8個字節屬於第一個數據塊。 –