1
0

Completed an audio module using a blocking I/O.

This commit is contained in:
Alexander Andreev 2024-03-21 17:50:20 +04:00
parent 64176055d0
commit f13e7e20fd
Signed by: Arav
GPG Key ID: 25969B23DCB5CA34
2 changed files with 61 additions and 35 deletions

View File

@ -4,25 +4,7 @@
#include <stdio.h>
#include <string.h>
int audio_default_callback(const void *input, void *output,
unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData) {
(void)timeInfo;
(void)statusFlags;
audio_t *aud = (audio_t *)userData;
int encLen = opus_encode_float(aud->opusEnc, (float *)input, frameCount, aud->opusBuf, aud->opusBufSz);
(void)encLen;
int frameSize = opus_decode_float(aud->opusDec, aud->opusBuf, aud->opusBufSz, (float *)output, frameCount, 0);
(void)frameSize;
// printf("%i %i | %li %li\n", encLen, frameSize, frameCount, aud->opusBufSz);
return paContinue;
}
int audio_init_default(audio_t *aud, int channels, int sampleRate, int frameSize, PaStreamCallback callback) {
int audio_init(audio_t *aud, int channels, int sampleRate, int frameSize) {
PaError paErr;
int opusErr;
@ -31,9 +13,6 @@ int audio_init_default(audio_t *aud, int channels, int sampleRate, int frameSize
return -1;
}
aud->opusBufSz = frameSize * channels;
aud->opusBuf = (uint8_t *)malloc(aud->opusBufSz * sizeof(uint8_t));
aud->opusEnc = opus_encoder_create(sampleRate, channels, OPUS_APPLICATION_VOIP, &opusErr);
if (opusErr != OPUS_OK) {
fprintf(stderr, "An Opus encoder cannot be created: %s\n", opus_strerror(opusErr));
@ -46,12 +25,15 @@ int audio_init_default(audio_t *aud, int channels, int sampleRate, int frameSize
return -1;
}
if ((paErr = Pa_OpenDefaultStream(&aud->stream, channels, channels, paFloat32,
sampleRate, frameSize, callback, aud)) != paNoError) {
if ((paErr = Pa_OpenDefaultStream(&aud->stream, channels, channels, AUDIO_SAMPLE_FORMAT,
sampleRate, frameSize, NULL, NULL)) != paNoError) {
fprintf(stderr, "Cannot open a PortAudio stream: %s\n", Pa_GetErrorText(paErr));
return -1;
}
aud->bufferSz = frameSize * channels;
aud->buffer = (audio_sample_t *)malloc(aud->bufferSz * sizeof(audio_sample_t));
if ((paErr = Pa_StartStream(aud->stream)) != paNoError) {
fprintf(stderr, "Cannot start a PortAudio stream: %s\n", Pa_GetErrorText(paErr));
return -1;
@ -80,14 +62,55 @@ int audio_destroy(audio_t *aud) {
return -1;
}
if (aud->buffer)
free(aud->buffer);
if (aud->opusEnc)
opus_encoder_destroy(aud->opusEnc);
if (aud->opusDec)
opus_decoder_destroy(aud->opusDec);
if (aud->opusBuf)
free(aud->opusBuf);
return 0;
}
/*
int encLen = opus_encode_float(aud->opusEnc, (float *)input, frameCount, aud->opusBuf, aud->opusBufSz);
(void)encLen;
int frameSize = opus_decode_float(aud->opusDec, aud->opusBuf, aud->opusBufSz, (float *)output, frameCount, 0);
(void)frameSize;
*/
int audio_read(audio_t *aud, uint8_t *outputData, size_t outputLen) {
PaError paErr;
if ((paErr = Pa_ReadStream(aud->stream, aud->buffer, aud->bufferSz)) != paNoError) {
fprintf(stderr, "Cannot read from a PortAudio stream: %s\n", Pa_GetErrorText(paErr));
return -1;
}
int encodedLen = opus_encode_float(aud->opusEnc, aud->buffer, aud->bufferSz, outputData, outputLen);
if (encodedLen < 0) {
fprintf(stderr, "Opus failed to encode: %s\n", opus_strerror(encodedLen));
return -1;
}
return 0;
}
int audio_write(audio_t *aud, const uint8_t *inputData, size_t inputLen) {
PaError paErr;
int frameSize = opus_decode_float(aud->opusDec, inputData, inputLen, aud->buffer, aud->bufferSz, 0);
if (frameSize < 0) {
fprintf(stderr, "Opus failed to decode: %s\n", opus_strerror(frameSize));
return -1;
}
if ((paErr = Pa_WriteStream(aud->stream, aud->buffer, aud->bufferSz)) != paNoError) {
fprintf(stderr, "Cannot write to a PortAudio stream: %s\n", Pa_GetErrorText(paErr));
return -1;
}
return 0;
}

View File

@ -7,19 +7,22 @@
#include <opus/opus.h>
#include <portaudio.h>
#define AUDIO_SAMPLE_FORMAT paFloat32
typedef float audio_sample_t;
typedef struct audio_t {
PaStream *stream;
PaStream *stream;
OpusEncoder *opusEnc;
OpusDecoder *opusDec;
uint8_t *opusBuf;
size_t opusBufSz;
audio_sample_t *buffer;
size_t bufferSz;
} audio_t;
int audio_default_callback(const void *input, void *output,
unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData);
int audio_init_default(audio_t *aud, int channels, int sampleRate, int frameSize, PaStreamCallback *callback);
int audio_init(audio_t *aud, int channels, int sampleRate, int frameSize);
int audio_destroy(audio_t *aud);
int audio_read(audio_t *aud, uint8_t *outputData, size_t outputLen);
int audio_write(audio_t *aud, const uint8_t *inputData, size_t inputLen);
#endif /* _AUDIO_H_ */