开发者

Converting Milliseconds to Timecode

开发者 https://www.devze.com 2022-12-22 10:23 出处:网络
I have an audio project I\'m working on using BASS from Un4seen. This library uses BYTES mainly but I have a conversion in place that let\'s me show the current position of the song in Milliseconds.

I have an audio project I'm working on using BASS from Un4seen. This library uses BYTES mainly but I have a conversion in place that let's me show the current position of the song in Milliseconds.

Knowing that MS = Samples * 1000 / SampleRate and that Samples = Bytes * 8 / Bits / Channels

So here's my main issue and it's fairly simple... I have a function in my project that converts the Milliseconds to TimeCode in Mins:Secs:Milliseconds.

Public Function ConvertMStoTimeCode(ByVal lngCurrentMSTimeValue As Long)
        ConvertMStoTimeCode = CheckForLeadingZero(Fix(lngCurrentMSTimeValue / 1000 / 60)) & ":" & _
        CheckForLeadingZero(Int((lngCurrentMSTimeValue / 1000) Mod 60)) & ":" & _
        CheckForLeadingZero(Int((lngCurrentMSTimeValue / 10) Mod 100))
End Function

Now the issue comes within the Seconds calculation. Anytime the MS calculation is over .5 the seconds place rounds up to the next second. So 1.5 seconds actually prin开发者_如何学JAVAts as 2.5 seconds. I know for sure that using the Int conversion causes a round down and I know my math is correct as I've checked in a calculator 100 times. I can't figure out why the number is rounding up. Any suggestions?


There is a flaw in your seconds conversion logic. For instance, suppose you want to convert 1500 ms. Your code to calculate seconds:

Int((lngCurrentMSTimeValue / 1000) Mod 60)

Would return 2. 1500 ms is not over two seconds! To calculate seconds, perform integer division (the "\" operator) of the milliseconds by 1000:

(lngCurrentMSTimeValue \ 1000) Mod 60

This returns 1 as expected. The following function is all you need. It even eliminates the need for your CheckForLeadingZero function by using the built-in Format function:

Public Function ConvertMStoTimeCode(ByVal lngCurrentMSTimeValue As Long)

  Dim minutes As Long
  Dim seconds As Long
  Dim milliseconds As Long

  minutes = (lngCurrentMSTimeValue / 1000) \ 60
  seconds = (lngCurrentMSTimeValue \ 1000) Mod 60
  milliseconds = lngCurrentMSTimeValue Mod 1000

  ConvertMStoTimeCode = Format(minutes, "00") & ":" & Format(seconds, "00") & _
    ":" & Format(milliseconds, "000")

End Function


For now this works:

Public Function ConvertMStoTimeCode(ByVal lngCurrentMSTimeValue As Long)
Dim strMinute As String
Dim strSecond As String
Dim strFrames As String

strMinute = CheckForLeadingZero(Fix(lngCurrentMSTimeValue / 1000 / 60))
strSecond = CheckForLeadingZero(Int((lngCurrentMSTimeValue / 1000) Mod 60))
strFrames = CheckForLeadingZero(Int((lngCurrentMSTimeValue / 10) Mod 100))

If (strFrames > 49) Then
    strSecond = CheckForLeadingZero(Int((lngCurrentMSTimeValue / 1000) Mod 60) - 1)
End If

ConvertMStoTimeCode = strMinute & ":" & strSecond & ":" & strFrames

End Function


Here's a Processing/Java equivalent that's fairly straightforward to repurpose.

String timecodeString(int fps) {
  float ms = millis();
  return String.format("%02d:%02d:%02d+%02d", floor(ms/1000/60/60),    // H
                                              floor(ms/1000/60),       // M
                                              floor(ms/1000%60),       // S
                                              floor(ms/1000*fps%fps)); // F
}
0

精彩评论

暂无评论...
验证码 换一张
取 消