> А что за карточка? "Чудо" под названием 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; }