Old 22nd November 2022, 12:22   #1
dickchuck
Junior Member
 
Join Date: Jan 2011
Posts: 25
Need length of playing track

SendMessage(plugin.hwndParent, WM_WA_IPC, 1, IPC_GETOUTPUTTIME) is unreliable in that it works for some files, but very often returns -1 meaning an error.
Not sure how there can be an error when Winamp clearly knows and correctly displays the track length in the playlist and must use this info to place the seek bar during playback. Anyone know why there might be an error / how to avoid?
I am looking into using
SendMessage(plugin.hwndParent, WM_WA_IPC, IPC_GET_BASIC_FILE_INFO, (WPARAM)&fileInfo)
but that seems like overkill. Also, I am not clear how that function works - does it scan the file and count music frames, or look for track length ID3 tags...? Yuck. Frustrating since Winamp obviously has the info I need.
Thanks ahead of time for any help.
dickchuck is offline   Reply With Quote
Old 22nd November 2022, 23:51   #2
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: No longer on the streets of Kings County, CA.
Posts: 3,218
Which files are returning -1? Are they playing at the time it's queried?
thinktink is offline   Reply With Quote
Old 23rd November 2022, 09:13   #3
dickchuck
Junior Member
 
Join Date: Jan 2011
Posts: 25
Ostensibly, it's the playing file. Now that you ask that, I'm going to double check if it's possible I am sending that message before play actually starts. I am writing a lyrics visualizer that starts its processing when IPC_PLAYING_FILE received via callback/subclass. I was assuming, and my subsequent initializing probably insures that play is already in progress by the time I check for it. Maybe not?

Can you confirm whether IPC_GETOUTPUTTIME should be not -1 as soon as IPC_PLAYING_FILE received?
dickchuck is offline   Reply With Quote
Old 25th November 2022, 07:03   #4
dickchuck
Junior Member
 
Join Date: Jan 2011
Posts: 25
I think that was it. After getting the play/start message, I open a file and parse it into memory. It never occurred to me that all of that would finish before play actually begins. I put in a loop to wait for > -1 return from length check before proceeding; loop seems to never need more than a single extra pass to get a value... curious.
dickchuck is offline   Reply With Quote
Old 25th November 2022, 16:05   #5
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: No longer on the streets of Kings County, CA.
Posts: 3,218
Be careful with that loop, if a file is an online continuous stream or a media file hosted on a server that doesn't support range requests or a file handled by an old input plugin that doesn't have seeking support then your loop could potentially never break and cause a hang.
thinktink is offline   Reply With Quote
Old 27th November 2022, 15:09   #6
dickchuck
Junior Member
 
Join Date: Jan 2011
Posts: 25
Good tip - it is a local file, but the loop is limited to an arbitrary 100000000 tries which seems to be massive overkill.

BUT I did notice more peculiar behavior. After waiting for non -1 playback time from IPC_GETOUTPUTTIME mode 0, my program proceeds to get track length and then goes on to a state of rendering information based on playback position. While I was not surprised that syncing to Winamp "clock" drifts from and runs slower than syncing to system clock elapse, I WAS surprised to find that some scenarios - typically when playing a file for the first time since loading a playlist, and strangely more regularly when starting playback by double clicking the list as opposed to cursoring to and pressing play - cause a subsequent read from playback position to be EARLIER. For instance, I keep track of the last play time read in the loop, in compare to the current pass - and trigger a text box update if the current is less than the previous. For instance, after an early read of 52 ms, I get a read of 48 ms. WEIRD.

Maybe I just post this line of inquiry into a new forum thread. I am not clear on the exact mechanism Winamp uses to track playtime; to explain observations I have assumed it is based on frames played/bit rate/etc. instead of tracking real time. The phenomenon seems to always be in the first few reads of playback and I guess with tag reading the estimation of actual music time can be jittery. I never expected it to swing negative and I am not sure why it does.

Note, I only found this behavior because I know of no good way to sense FFWD or RWND from my plugin. I decided that if the playback time ever reads less than a previous read, there was a RWND event from the use. NOT SO I have discovered. By the way, if anyone knows a better way to detect rewind or fast-forward pleas advise. I plan to increase the gap between current and previous reads to have to exceed some threshold before calling it a real RWND - like must be less in time by at least 150 ms or so.
dickchuck is offline   Reply With Quote
Old 28th November 2022, 01:50   #7
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: No longer on the streets of Kings County, CA.
Posts: 3,218
Have a careful look at IPC_CB_MISC inside wa_ipc.h, specifically IPC_CB_MISC_STATUS. The notes in the comments section indicate that it's sent when there's a FF or RW. You will have to either /class or hook the main Winamp HWND to see it.
thinktink is offline   Reply With Quote
Old 28th November 2022, 09:39   #8
dickchuck
Junior Member
 
Join Date: Jan 2011
Posts: 25
Hi, I will have a look at that. I ran across it before, but my .h describes that message as being sent on play/stop/pause/rwnd/ffwd so I am not sure how to deconvolute which case I am in without an appeal to playback time - which now I don't trust.

In fact, I just did some analysis that records a stream of playback time values returned from winamp (sampled with an arbitrary 100000 count loop between) along with elapsed time measured with GetTickCount(); here's what I found... (ticks ms) winamp ms, ...

On startup, I play the first file in my playlist: (0) 0, (0) 0, (15) 0, (15) 0, (31) 0, (31) 0, (47) 50, (47) 52, (62) 48, (62) 48 ... (172) 48.

Of all the things that make this time read out hard to use, the most egregious to me is that the "time" goes from 52 ms played, to 48 - where it stalls for several reads - before proceeding in a more normal way.

What's more, on second playback the numbers proceed more quickly and in an always increasing way.

I love me some Winamp, but I really think they dropped the ball by not supplying more and unique call backs for events. Moreover, I am subclassing the wndProc to catch IPC_STOPPLAYING and IPC_PLAYING_FILE already. Why oh why did they double up stop/play with pause/ffwd/rwnd when stop and play effectively have their own messages already. More to the point, there should be a separately identifiable message sent for each control surface command that a user might use! I'm ranting now because of all the hours I've wasted on this already.

If you can suggest a clean way to identify FFWD and RWND with specifics Im all ears. I will report back what I learn. THANKS
dickchuck is offline   Reply With Quote
Old 28th November 2022, 15:57   #9
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: No longer on the streets of Kings County, CA.
Posts: 3,218
I had to open my source code for one of my plugins to find this: http://forums.winamp.com/showthread....18#post3045918

If memory serves, these are sent to the Winamp main HWND in the low word of WPARAM of a WM_COMMAND message. I don't know if they will be triggered for seekbar seeks. At the moment this is all that I could find.
thinktink is offline   Reply With Quote
Old 29th November 2022, 16:53   #10
dickchuck
Junior Member
 
Join Date: Jan 2011
Posts: 25
Ah, I realize I wasn't being clear before - by FFWD and RWND I meant specifically using the seek/shuttle bar or commands and not next track, previous track. So, two things come to mind...
1) Do you know which of the WM_COMMAND values is for the shuttle bar? I can probably get this with some checking, but I'd take advantage of any time others have put in on this. I've seen that list before but it's laden with Button# like terms with no description of what they do. I found a VB.net package that wrapped each command in a well documented function call suggesting that 40148 is FFWD which on your list is Shift+Butn5 or similar. I'll followup.
2) I did some more digging, and thought I'd share. While monitoring only for STOPPLAYING, ISPLAYINGFILE, MISC_TITLE and MISC_STATUS...
upon playback by double clicking while stopped: TITLE, TITLE, TITLE, ISPLAYING, STATUS
same for pressing play while stopped
for pressing play while playing: TITLE, STOP, TITLE, TITLE, TITLE, STATUS, ISPLAYING, STATUS
same for natural end of song and advance to next track
same for next/prev while playing
stop while playing: TITLE, STOP, STATUS
same for natural stop at end of list
FFWD/RWND seek while playing: TITLE
next track/prev track while not playing (not at end of list): TITLE, STOP, STATUS
if at end - no message
stop while stopped - no message

Note. these are are callbacks sponsored by Winamp not based on polling or SendMessage inquiry.
dickchuck is offline   Reply With Quote
Old 29th November 2022, 17:11   #11
dickchuck
Junior Member
 
Join Date: Jan 2011
Posts: 25
Also, as if the Winamp gods are trying to drive me to suicide, moving the shuttle/seek bar does not issue a WM_COMMAND message; even though things like right click on >| and chose forward 5 sec do (in fact that sends two messages since it is menu mediated).
dickchuck is offline   Reply With Quote
Old 29th November 2022, 20:52   #12
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: No longer on the streets of Kings County, CA.
Posts: 3,218
Quote:
Originally Posted by dickchuck View Post
...moving the shuttle/seek bar does not issue a WM_COMMAND message...
I noticed that as well using an external program to capture window messages. The only other thing I can think of is to look for a message in response to seek bar seeks, or to investigate the WASABI APIs for a solution.
thinktink is offline   Reply With Quote
Old 30th November 2022, 23:05   #13
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: No longer on the streets of Kings County, CA.
Posts: 3,218
Is somebody changing the posts in this thread? I got a notification of a new reply but when I opened the forums there was no new reply and the message that I saw in the email now shows up in an earlier post. Either that or I'm really confused.
thinktink is offline   Reply With Quote
Old 30th November 2022, 23:43   #14
dickchuck
Junior Member
 
Join Date: Jan 2011
Posts: 25
I have to move on to other aspects of this project, but I have decided on the following less than great 'solution' that seems to work. I use STOPPLAYING and PLAYINGFILE messages to detect begin / end of play and file change since the MISC_TITLE message is posted repeatedly for some reason and the MISC_STATUS is oddly different for different situations. The two I've chosen are reliably sent only once per event and in a usable way for my purposes.
For RWND/FFWD I simply bypass checking for seek until the song has played back for a time period (e.g. 1 sec) before checking - this time passage measured using system clock. This seems to get past the jittery readings from Winamp where playback time goes up and then down (?) on subsequent reads. After that initial period, then using Winamp times, if thisTime - lastTime > 200 ms I consider that a seek FFWD condition and if lastTime - thisTime > 200 ms I consider that a RWND condition.
To be clear, these checks are within a loop that draws some graphics to a bitmap based on playback position; it keeps track of the system clock and triggers a window repaint and checks RWND/FFWD each passage of 40 ms. This is an effort to pursue a visual refresh rate of 25 frames per second. I think Winamp time is based on MP3 frame processing not actual elapsed time; not sure for FFWD or RWND seek bar if it uses MP3 seek table from Xing header when available or not... maybe it guesses based on file position. Either way, the variation from real time isn't far enough from 40 ms to interfere with my assumption that anything greater than 200 ms was a user intervention.
Just in case anyone else is stuck on this.
I suspect I can cause this algorithm trouble by repeatedly/quickly moving the seek bar to different spots. I'm not sure if I rewind to start with bar how the behavior of Winamp might change versus pressing play to restart - in so far as the start up jitter is concerned.
dickchuck is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > Winamp Development

Tags
plugin, track length

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump