Results 1 to 1 of 1
I have some code below that basically initialises PortAudio and opens an Ogg file specifed as argv[1]. Not sure what to do next. The PortAudio tutorials on their site are ...
- 02-16-2009 #1Just Joined!
- Join Date
- Feb 2009
- Posts
- 1
How to use PortAudio and libvorbisfile to play Ogg file?
I have some code below that basically initialises PortAudio and opens an Ogg file specifed as argv[1]. Not sure what to do next. The PortAudio tutorials on their site are very limited and the example code included with V19 only covers testing audio, finding devices, testing latency, and generating tones.
I am pretty sure it's not PortAudio that is the problem here, but what to do PortAudio's callback regarding audio data that is given from libvorbisfile.
Audacity and Mixxx are a few example programs using PortAudio successfully but they have not been helpful as their implementations seem to be very specific. I also have tried to understand mpg123's PA implementation.
So what do I pass? Code below.
EDIT: Now plays sound, but not good sound. How do I advance in the file?Code:/* Compile with: gcc -o portogg -D__DEBUG__ -Wall -ansi -pedantic -std=c99 -Wfatal-errors -lportaudio -lvorbisfile portogg.c */ #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <portaudio.h> #include <vorbis/vorbisfile.h> #define INPUTCHANNELS 0 #define BYTES_TO_READ 4096 typedef struct { struct OggVorbis_File file; struct vorbis_info *info; double audio_length; int endian; int position; } audioData_s; static int oggCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags, void *userData ) { (void)inputBuffer; /* Prevent unused variable warnings */ audioData_s *data = (audioData_s*)userData; char *out = (char*)outputBuffer; long ret; ret = ov_read(&data->file, out, BYTES_TO_READ, data->endian, data->info->channels, 1, &data->position); fprintf(stdout, "ret = %ld\n", ret); if (ret == 0) return 1; return 0; } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <ogg file>\n", argv[0]); exit(EXIT_FAILURE); } PaError err; /* PortAudio types */ PaStream *stream; audioData_s audioData; FILE *ogg; bool streamFailure = false; int testvar = 1; /* Endianness */ if ((err = Pa_Initialize()) != paNoError) { fprintf(stderr, "Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err)); exit(EXIT_FAILURE); } ogg = fopen(argv[1], "rb"); if (ov_open(ogg, &audioData.file, NULL, 0) < 0) { fprintf(stderr, "Error decoding %s.\n", argv[1]); exit(EXIT_FAILURE); } audioData.info = ov_info(&audioData.file, -1); /* Information about Ogg file */ audioData.audio_length = ov_time_total(&audioData.file, -1); #ifdef __DEBUG__ fprintf(stdout, "Ogg filename: %s\n", argv[1]); fprintf(stdout, "Sample rate: %ld\n", audioData.info->rate); fprintf(stdout, "Number of channels: %d\n", audioData.info->channels); fprintf(stdout, "Lenght: %.3f seconds\n", audioData.audio_length); #endif if (ov_pcm_seek(&audioData.file, 0) != 0) { /* This is because some files do not do this automatically */ fprintf(stderr, "Error seeking file to position 0.\n"); } else { #ifdef __DEBUG__ fprintf(stdout, "Seeked file to position 0.\n"); #endif audioData.position = 0; } err = Pa_OpenDefaultStream(&stream, INPUTCHANNELS, audioData.info->channels, paFloat32, audioData.info->rate, BYTES_TO_READ, oggCallback, &audioData); if (err != paNoError) { fprintf(stderr, "Pa_OpenDefaultStream() returned an error: %s\n", Pa_GetErrorText(err)); streamFailure = true; } if(*(char *)&testvar) audioData.endian = 0; /* little endian */ else audioData.endian = 1; /* big endian */ err = Pa_StartStream( stream ); if( err != paNoError ) fprintf(stderr, "Error starting stream.\n"); #ifdef __DEBUG__ else fprintf(stdout, "Stream started successfully.\n"); #endif /* Call back starts now */ Pa_Sleep(1000*(int)audioData.audio_length); err = Pa_StopStream( stream ); if( err != paNoError ) fprintf(stderr, "Error stopping stream: %s\n", Pa_GetErrorText(err)); #ifdef __DEBUG__ else fprintf(stdout, "Stream stopped successfully.\n"); #endif err = Pa_CloseStream( stream ); if( err != paNoError ) fprintf(stderr, "Error closing stream: %s\n", Pa_GetErrorText(err)); #ifdef __DEBUG__ else fprintf(stdout, "Stream closed successfully.\n"); #endif ov_clear(&audioData.file); #ifdef __DEBUG__ fprintf(stdout, "Freed %s file from memory.\n", argv[1]); #endif err = Pa_Terminate(); if( err != paNoError ) fprintf(stderr, "PortAudio error: %s\n", Pa_GetErrorText(err)); #ifdef __DEBUG__ else fprintf(stdout, "PortAudio terminated.\n"); #endif if (streamFailure) exit(EXIT_FAILURE); exit(EXIT_SUCCESS); }


Reply With Quote