I'm new to SDL.
I'm developing a media player using SDL, and now I met the problem that the audio callback function is sometimes not called in time, and cause the audio a little fitful.
I use such piece of code to open the audio device:
wanted_spec.xxx = xxx;
wanted_spec.callback = audio_callback; //audio_callback is my audio callback function
SDL_OpenAudio(&wanted_spec, &spec);
My OS is Windows XP.
Do you know anything about that? Can someone suggest how to synchronize data feeding to callback function with 0 latency.
My Problem is instead of providing whole wav file through SDL_LoadWAV, I want to pass PCM samples (probably 1024 samples).(Design is like this I will be getting PCM samples)
But issue is, callback function is not called in time or calling is delayed which causes the sound to be fitful. I'm not able to syn passing of data to callback function.
Can you please suggest a way to synchronize passing data (Samples) to callback function or provide some application where data is passed in samples?
We need real values to fully answer your question.
What is your attempted buffer size?
Also realize that it is common for SDL to not give you what you want, so check what the actual spec buffer size is.
I've been using a binary mingw32 port of SDL on windows that won't give me buffers smaller than one second no matter what I request.
Related
I'm new to sound programming and ALSA. I'd like to create a little application, that for example prints out to the console when a frame of data is written to ALSA with snd_pcm_writei(...). Is that possible and if so, how?
Currently I'm thinking of registering a callback to ALSA so when an application calls snd_pcm_writei(...) the callback is executed. But I'm not sure that is how it works.
You can either use
blocking mode (the default), in which snd_pcm_write*() returns only when all the data has been written into the ring buffer (or when an error has occured), or
non-blocking mode (enabled with SND_PCM_NONBLOCK when opening, or snd_pcm_nonblock()), in which you can use poll()/epoll() etc. to get a notification.
Using an ALSA async handler works only with certain devices, and has all the drawbacks of signal handlers; it is deprecated.
I am working with a CAN application and am having some timing issues. It seems there is some time delta between when my CAN message write function completes and when the CAN message is actually transmitted. So I want to measure the time between the two. The write function is in C++, so it's a simple call to GetTickCount to know when the write function completes. It's knowing when the actual transmission happens that's the problem.
I am using Vector's CANalyzer to monitor my CAN bus, and heard it has a programming interface (CAPL). What I would like to do is grab the PC clock time at which a message has actually been transmitted. Is there any system-CAPL interface that I could use to do this?
It would be easier to measure the time in your C++ program. The CAN driver should provide some "TX confirmation callback function". The CAN driver calls this function as soon as the message has been successfully transmitted. You would need to configure the callback and to measure the time between your CAN write operation and this callback.
I am writing an application on Ubuntu Linux in C++ to read data from a serial port. It is working successfully by my code calling select() and then ioctl(fd,FIONREAD,&bytes_avail) to find out how many bytes are available before finally obtaining the data using read().
My question is this: Every time select returns with data, the number of bytes available is reported as 8. I am guessing that this is a buffer size set somewhere and that select returns notification to the user when this buffer is full.
I am new to Linux as a developer (but not new to C++) and I have tried to research (without success) if it is possible to change the size of this buffer, or indeed if my assumptions are even true. In my application timing is critical and I need to be alerted whenever there is a new byte on the read buffer. Is this possible, without delving into kernel code?
You want to use the serial IOCTL TIOCSSERIAL which allows changing both receive buffer depth and send buffer depth (among other things). The maximums depend on your hardware, but if a 16550A is in play, the max buffer depth is 14.
You can find code that does something similar to what you want to do here
The original link went bad: http://www.groupsrv.com/linux/about57282.html
The new one will have to do until I write another or find a better example.
You can try to play with the VMIN and VTIME values of the c_cc member of the termios struct.
Some info here, especially in the section 3.2.
Is there a way to check the number of bytes available from a USB device (printer in our case)?
We're using CreateFile and ReadFile and WriteFile for IO communications with our USB device, which works. But We can't figure out how much data is available without actually doing a read. We can't use GetFileSize, as even the documentation says you can't use it for a :
"nonseeking device such as a pipe or a communications device"...
So that doesn't work. Any suggestions? Are we doing our USB I/O incorrectly? Is there a better way to Read/Write to USB?
You first need to open up the port in asynchronous mode. To do that, pass the flag FILE_FLAG_OVERLAPPED to CreateFile. Then, when you call ReadFile, pass in a pointer to an OVERLAPPED structure. This does an asynchronous read and immediately returns ERROR_IO_PENDING without blocking (or, if the OS already has the data buffered, you might get lucky and get a successful read -- be prepared to handle that case).
Once the asynchronous I/O has started, you can then periodically check if it has completed with GetOverlappedResult.
This allows you to answer the question "are X bytes of data available?" for a particular value of X (the one passed to ReadFile). 95% of the time, that's good enough, since you're looking for data in a particular format. The other 5% of the time, you'll need to add another layer of abstraction top, where you keep doing asynchronous reads and store the data in a buffer.
Note that asynchronous I/O is very tricky to get right, and there's a lot of edge cases to consider. Carefully read all of the documentation for these functions to make sure your code is correct.
Can you use C#? If so you can access the USB port using System.IO.SerialPort class, and then set up a DataReceived event handler for incoming data. There is a BytesToRead property that tells you how much data is waiting to be read.
All of this must be available in native code, if I can find it I'll edit this.
EDIT: the best I can find for native is ReadPrinter - I don't see how to check if data is there, this will block if it's not.
Does anybody know any reasons why IMemAllocator:GetBuffer (Directshow) hangs, apart from all samples being in use?
I have a directshow application which uses GMFBridge by Geraint Davies to connect two graphs. The GMFBridge is used to be able to switch inputs, but I am not switching in this situation. The application captures audio and video, and should do that non-stop. But after about 10 hours it stops. I found out both audio and video got stuck in a call to IMemAllocator:GetBuffer:
/* _COM_SMARTPTR_TYPEDEF(IMemAllocator, IID_IMemAllocator); */
/* IMemAllocatorPtr m_pCopyAllocator; */
hr = m_pCopyAllocator->GetBuffer(&pOut, NULL, NULL, 0);
If all samples are in use, this function can block, but I am pretty sure this is not the case. There are two threads calling this function, one for the video and one for the audio samples. The Audio thread blocks first, and after the GetBuffer has returned a buffer for almost 60 video samples, the video thread blocks too. (this is about 2 seconds later)
After almost 8 hours both threads continue for a small period, first the audio thread, and after 45 buffers for audio samples have been returned, the video thread unblocks too.
So because both threads do not block at the same time, it looks to me there is not a problem with all samples being in use.
The stacktrace shows a function inside quartz.dll is being called at that moment.
UPDATE
It looks like there was a memoryleak caused by decoder filters already installed on the pc. The graph included decoding of mpeg, for example the audio decoding used a cyberlink decoder. After installing ffdshow, the ffdshow audio + video decoder was used instead, and the problem seems to be disappeared. Lesson learned, do not depend automatically on existing filters.
Not sure that I can debug this from the info given. Can you create a log file (create an empty file c:\gmfbridge.txt, run until it hangs, then zip the file and email it). Also, if you set up your symbols with _NT_SYMBOL_PATH, you could look at the stack trace to see where in quartz.dll the various threads are.
G