Re: debian, SDL1.2 & audio
> А что за карточка?
"Чудо" под названием VIA vt82c686.
> А если mp3 через xmms играть - оно с нормальной скоростью получается?
> А через mplayer?
Без проблем. И то и другое.
Да в общем-то и все прочие, даже нативные виндовые гамесы под wine/winex.
> Просто на карточке может стоять другой битрейт (например 48hz)..
Да, на 44100 она ругается.
Пробовал ему "подсунуть" 48kHz - эффект тот же, хотя через obtained audio
SDL_AudioSpec говорит, что вот 48kHz поддерживает.
Кстати, "о птичках" - почему-то в SDL_Init/SDL_InitSubsystem джойстик надо
"поднимать" только вместе с видео, иначе и не рекомендуют да и не работать
хотит .. это бага или фича ?
> Давай код в студию -- посмотрим.
attached.
За форматирование, pls, сильно не бить - это vc6 "постарался". :(
WBR, Burzumie.
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <signal.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>
#include <SDL/SDL.h>
#ifdef WIN32
// may be dangerous (!). will be removed
#define snprintf _snprintf
#pragma comment(lib, "SDL.lib")
//#pragma comment(lib, "vorbisfile_d.lib")
// static linking under win32
#pragma comment(lib, "ogg_static.lib")
#pragma comment(lib, "vorbis_static.lib")
#pragma comment(lib, "vorbisfile_static.lib")
#endif
#include <iostream>
using namespace std;
struct sStatic_init
{
Uint32 SDL_init_flags;
sStatic_init()
{
SDL_init_flags = SDL_INIT_AUDIO;
if (SDL_Init(SDL_init_flags) < 0)
{
cerr << "Couldn't initialize SDL: " << SDL_GetError() << endl;
exit(EXIT_FAILURE);
}
}
~sStatic_init()
{
SDL_QuitSubSystem(SDL_init_flags);
}
} static_init;
const char *filename = "1.ogg";
OggVorbis_File vf;
int current_section;
char pcmout[4096];
char buffer[65535];
static bool done = false;
int chunk_num = 0;
unsigned int data_carried = 0;
void my_audio_callback(void *userdata, Uint8 *stream, int len)
{
// for messages
char s[1024];
int filled = 0;
if(data_carried > 0)
{
memcpy(stream, buffer, data_carried);
filled = data_carried;
data_carried = 0;
}
do
{
// decode next chunk
long ret = ov_read(&vf, pcmout, sizeof(pcmout), 0, 2, 1, ¤t_section);
if (ret == 0)
{
// EOF
cerr << "EOF reached" << endl;
SDL_PauseAudio(1);
done = true;
return;
}
else
if (ret < 0)
{
/* error in the stream. Not a problem, just reporting it in
case we (the app) cares. In this case, we don't. */
cerr << "error in stream" << endl;
exit(1);
}
else
{
/* we don't bother dealing with sample rate changes, etc, but you'll have to */
int rest;
// will be end of buffer reached ?
if((filled + ret) > len)
{
rest = len - filled;
data_carried = (filled + ret) - len; // must be always > 0
if(data_carried > sizeof(buffer))
{
snprintf(s, sizeof(s), "data overflow: carried %i bytes in chunk %i, only %i reserved", data_carried, chunk_num, sizeof(buffer));
#ifdef WIN32
MessageBox(0, s, "error", NULL);
#else
cerr << s << endl;
#endif
exit(1);
}
else
{
memcpy(buffer, pcmout+(ret - data_carried), data_carried);
}
}
else
{
rest = ret;
}
memcpy(stream + filled, (Uint8 *)(pcmout), rest);
filled += ret;
}
} while(filled < len); // must fill all 'stream' buffer
++chunk_num;
}
void sighandler(int sig)
{
done = true;
}
/*
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
*/
int main()
{
SDL_AudioSpec *desired, *obtained;
SDL_AudioSpec *hardware_spec;
desired = new SDL_AudioSpec;
obtained = new SDL_AudioSpec;
desired->freq=48000;
desired->format=AUDIO_S16LSB;
desired->channels=2;
desired->samples=4096;
desired->callback=my_audio_callback;
desired->userdata=NULL;
char s[1024];
// open the audio device
int r = SDL_OpenAudio(desired, obtained);
if ( r < 0 )
{
snprintf(s, sizeof(s), "Couldn't open audio: %s", SDL_GetError());
#ifdef WIN32
MessageBox(0, s, "error", NULL);
#else
cerr << s << endl;
#endif
return 1;
}
// desired spec is no longer needed
// delete desired;
hardware_spec = obtained;
FILE *f = fopen(filename, "rb");
if(f == NULL)
{
snprintf(s, sizeof(s), "Error opening input file: %s", strerror(errno));
#ifdef WIN32
MessageBox(0, s, "error", NULL);
#else
cerr << s << endl;
#endif
return 1;
}
if(ov_open(f, &vf, NULL, 0) < 0)
{
snprintf(s, sizeof(s), "Input file does not appear to be an Ogg bitstream.");
#ifdef WIN32
MessageBox(0, s, "error", NULL);
#else
cerr << s << endl;
#endif
return 1;
}
#ifndef WIN32
signal(SIGHUP, sighandler);
signal(SIGINT, sighandler);
signal(SIGQUIT, sighandler);
signal(SIGTERM, sighandler);
signal(SIGTTOU, SIG_IGN);
#endif
char audio_driver_name[32];
snprintf(s, sizeof(s), "Using audio driver: %s", SDL_AudioDriverName(audio_driver_name, 32));
#ifdef WIN32
MessageBox(0, s, "info", NULL);
#else
struct audio_hw_fmt
{
char *fmt_name;
Uint16 fmt;
} audio_hw_fmt_tbl[] =
{
{ "AUDIO_U8", 0x0008 },
{ "AUDIO_S8", 0x8008 },
{ "AUDIO_U16LSB", 0x0010 },
{ "AUDIO_S16LSB", 0x8010 },
{ "AUDIO_U16MSB", 0x1010 },
{ "AUDIO_S16MSB", 0x9010 }
};
cout << s << endl;
cout << "Obtained hardware SDL_AudioSpec are: " << endl;
cout << " frequency: " << int(hardware_spec->freq) << endl;
cout << " format: " << int(hardware_spec->format);
char *sp = NULL;
for(unsigned int i = 0; i < sizeof(audio_hw_fmt_tbl); ++i)
{
if(audio_hw_fmt_tbl[i].fmt == hardware_spec->format)
{
sp = audio_hw_fmt_tbl[i].fmt_name;
break;
}
}
cout << " (" << (sp != NULL ? sp : "unknown") << ")" << endl;
cout << " channels: " << int(hardware_spec->channels) << endl;
cout << " samples: " << int(hardware_spec->samples) << endl;
#endif
// Start playing
SDL_PauseAudio(0);
while ( (done == false) && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING) )
{
SDL_Delay(1000);
}
SDL_PauseAudio(1);
// cleanup
SDL_CloseAudio();
ov_clear(&vf);
delete obtained;
snprintf(s, sizeof(s), "done");
#ifdef WIN32
MessageBox(0, s, "info", NULL);
#else
cout << s << endl;
#endif
return 0;
}
Reply to: