通过c

时间:2015-07-14 12:40:31

标签: c sockets audio tcp

我(尝试通过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()函数之外,它似乎还可以。不过,谢谢你的教育秘诀!

2 个答案:

答案 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.
 }