我正在尝试将音频发送到我通过套接字构建的服务器。我正在为客户端使用C.基本上我的代码记录了最多10秒的音频,然后我想通过套接字将它发送到我的服务器。如何发送通过C中的套接字录制的音频?我不想将音频保存为文件...我想将其直接发送到服务器。
这是我的代码:
// Standard libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
// Audio libraries
#include "portaudio.h"
// Audio parameters
#define RECORD_AUDIO_THRESHOLD 0.003
#define SILENCE_SECONDS 1
#define MAX_RECORDING_SECONDS 10
#define AUDIO_FORMAT paFloat32
typedef float SAMPLE_TYPE;
#define NUM_INPUT_CHANNELS 1
#define NUM_OUTPUT_CHANNELS 1
#define SAMPLE_RATE 44100
#define FRAMES_PER_BUFFER 512
// Server details
#define SERVER_ADDRESS "127.0.0.1"
#define SERVER_PORT 8080
// Global variables
int sock = 0;
// ######################## Structures ########################
typedef struct
{
int recording;
int maxFrameIndex;
int currentFrameIndex;
int silenceStartFrameIndex;
double averageAmplitude;
SAMPLE_TYPE *recordedSamples;
}
paAudioData;
// ######################## Helper Functions ########################
void setup(void)
{
}
// ######################## Helper Functions ########################
// ######################## Callbacks ########################
static int paListeningCallback( const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paAudioData *data = (paAudioData*)userData;
const SAMPLE_TYPE *rptr = (const SAMPLE_TYPE*)inputBuffer;
SAMPLE_TYPE *wptr = &data->recordedSamples[data->currentFrameIndex * NUM_INPUT_CHANNELS];
unsigned long framesLeft = data->maxFrameIndex - data->currentFrameIndex;
SAMPLE_TYPE amplitude, frameData;
long framesToCalc, i;
int j;
// Prevent unused variable warnings.
(void) outputBuffer;
(void) timeInfo;
(void) statusFlags;
(void) userData;
if (framesLeft < framesPerBuffer && data->recording)
framesToCalc = framesLeft;
else
framesToCalc = framesPerBuffer;
for (i = 0; i < framesToCalc; i++)
{
frameData = *rptr++;
amplitude = frameData;
if (amplitude < 0) amplitude = -amplitude; // ABS
if ((amplitude - data->averageAmplitude) >= RECORD_AUDIO_THRESHOLD)
{
if (!(data->recording))
{
data->recording = 1;
data->currentFrameIndex = 0;
printf("Recording...\n");
}
data->silenceStartFrameIndex = 0;
for (j = 0; j < NUM_INPUT_CHANNELS; j++) *wptr++ = frameData;
}
else if (data->recording)
{
if (data->silenceStartFrameIndex == 0) data->silenceStartFrameIndex = data->currentFrameIndex + i;
if ((data->currentFrameIndex + i) == data->silenceStartFrameIndex + (SILENCE_SECONDS * SAMPLE_RATE * NUM_INPUT_CHANNELS))
{
data->recording = 0;
data->currentFrameIndex += i;
printf("Stopped recording.\n");
// TODO: Send audio to server via socket
return 0;
}
for (j = 0; j < NUM_INPUT_CHANNELS; j++) *wptr++ = frameData;
}
}
data->currentFrameIndex += framesToCalc;
return 0;
}
// ######################## Main ########################
int main(void)
{
PaStream* stream;
PaError err;
paAudioData data;
int i,
totalFrames,
numSamples,
numBytes;
struct sockaddr_in address;
int valread;
struct sockaddr_in serv_addr;
char buffer[2048] = {0};
setup();
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERVER_PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, SERVER_ADDRESS, &serv_addr.sin_addr) <= 0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
// Initialize audio data
data.maxFrameIndex = totalFrames = MAX_RECORDING_SECONDS * SAMPLE_RATE;
data.currentFrameIndex = 0;
numSamples = totalFrames * NUM_INPUT_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE_TYPE);
data.recordedSamples = (SAMPLE_TYPE *) malloc(numBytes);
data.averageAmplitude = 0;
data.recording = 0;
// Initialize PortAudio
err = Pa_Initialize();
if (err != paNoError) goto paError;
// Open an audio listening stream
err = Pa_OpenDefaultStream( &stream,
NUM_INPUT_CHANNELS,
0,
AUDIO_FORMAT,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paListeningCallback,
&data );
if (err != paNoError) goto paError;
// Start passive audio listening
err = Pa_StartStream(stream);
if (err != paNoError) goto paError;
Pa_Sleep(10000);
// Terminate PortAudio
err = Pa_Terminate();
if (err != paNoError) goto paError;
// Print PortAudio error and exit
paError:
printf("PortAudio error: %s\n", Pa_GetErrorText(err));
return 0;
return 0;
}