我(尝试通过C中的套接字尝试传递.wav文件失败)。
以下代码读取.wav文件并将其分配给short samples变量(num_samples是其大小)。
char* filename = "./test.wav";
FILE* f;
short* samples; // stored signal
int num_samples, curr_samples; // count of signal samples
if ((f = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "cannot open %s\n", filename);
return;
}
/* reads the .wav file into memory (samples) */
if (read_wav(f, &samples, &num_samples) < 0) {
return;
}
fclose(f);
然后,将样本迭代加载到缓冲区并通过套接字
int buffer_size = 320;
unsigned char buffer[buffer_size];
short bufferSamples[buffer_size/2];
int curr_samples = 0;
while(curr_samples < num_samples) {
bzero(buffer,buffer_size);
bzero(bufferSamples,buffer_size/2);
// Store samples in short array
for (i = curr_samples; i < buffer_size/2 + curr_samples; i++) {
bufferSamples[i-curr_samples] = *(samples + i);
}
// assign to buffer
for (i = 0; i < buffer_size; i+=2) {
unsigned char upper = bufferSamples[i/2] & 0xFF;
unsigned char lower = bufferSamples[i/2] >> 8;
buffer[i] = lower;
buffer[i+1] = upper;
}
n = write(sockfd,buffer,strlen(buffer));
if (n < 0) error("ERROR writing to socket");
// sleep and increment
usleep(10000);
curr_samples += buffer_size/2;
}
为简单起见,我没有发布整个代码(套接字定义等)
我相信我已经确认bufferSamples正确地将信号存储为每次迭代的短路(通过将其打印与命令的输出进行比较&#34; od -s test.wav&#34;),所以我怀疑当我将短数组分配给char缓冲区时出现问题。我试图改变结束无济于事。
服务器还从我无法访问的另一个客户端读取输入,但它正确处理其输入,因此问题在于此客户端。
我对套接字和字节转换没什么经验,所以如果你能给我一些见解,我将不胜感激。希望解决方案对经验丰富的人来说非常明显。
编辑:事实证明,问题在于用于将信号传递给此代码的接口。所以,除了strlen()函数之外,它似乎还可以。不过,谢谢你的教育秘诀!
答案 0 :(得分:2)
大多数情况下这看起来不错。代码可能更整洁,更多函数可以在Short和2x char等之间进行转换...以提高可读性,但是你所写的内容看起来一目了然。
但是有一个问题。
n = write(sockfd,buffer,strlen(buffer));
strlen()
用于计算空终止字符串的长度。
如果您的缓冲区有任何0字节,strlen
将停止计数。您可能希望每次sizeof(buffer)
答案 1 :(得分:1)
我同意另一个答案,即使用strlen
肯定会导致您遇到问题。我还在回答说你正在做很多不必要的工作,这些工作也可能容易出错。将样本复制到另一个短缓冲区,然后将该短缓冲区复制到字符缓冲区中都可以跳过。您将遇到的另一个问题是当您到达缓冲区的末尾时。如果它不是320字节的倍数,那么你只需要读取缓冲区的末尾。
int numBytesRemaining = num_samples * 2;
int numBytesToSend = 0;
int numBytesSent = 0;
unsigned char* pBuf = (unsigned char*)samples;
while (numBytesRemaining)
{
numBytesThisTime = 320;
// don't read past the end of the buffer.
if (numBytesThisTime > numBytesRemaining)
numBytesThisTime = numBytesRemaining;
// just in case fewer bytes were written than requested.
// 0 is an example.
numBytesWritten = write(sockfd,pBuf,numBytesThisTime);
if (numBytesWritten < 0) error("ERROR writing to socket");
// sleep and increment
usleep(10000);
// only advance by numBytesWritten
numBytesRemaining -= numBytesWritten;
pBuf += numBytesWritten; // advance the pointer.
}