Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
18a81b3c
Commit
18a81b3c
authored
Oct 23, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Nov 09, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dmime: Better implement performance times with tempo track.
parent
29940435
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
77 additions
and
26 deletions
+77
-26
performance.c
dlls/dmime/performance.c
+68
-17
dmime.c
dlls/dmime/tests/dmime.c
+9
-9
No files found.
dlls/dmime/performance.c
View file @
18a81b3c
...
...
@@ -21,6 +21,7 @@
#include "dmime_private.h"
#include "dmusic_midi.h"
#include "wine/rbtree.h"
#include <math.h>
WINE_DEFAULT_DEBUG_CHANNEL
(
dmime
);
...
...
@@ -677,20 +678,39 @@ done:
static
HRESULT
WINAPI
performance_MusicToReferenceTime
(
IDirectMusicPerformance8
*
iface
,
MUSIC_TIME
music_time
,
REFERENCE_TIME
*
time
)
{
static
int
once
;
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
MUSIC_TIME
tempo_time
,
next
=
0
;
DMUS_TEMPO_PARAM
param
;
double
tempo
,
duration
;
HRESULT
hr
;
if
(
!
once
++
)
FIXME
(
"(%p, %ld, %p): semi-stub
\n
"
,
This
,
music_time
,
time
);
else
TRACE
(
"(%p, %ld, %p)
\n
"
,
This
,
music_time
,
time
);
TRACE
(
"(%p, %ld, %p)
\n
"
,
This
,
music_time
,
time
);
if
(
!
time
)
return
E_POINTER
;
*
time
=
0
;
if
(
!
This
->
master_clock
)
return
DMUS_E_NO_MASTER_CLOCK
;
/* FIXME: This should be (music_time * 60) / (DMUS_PPQ * tempo)
* but it gives innacurate results */
*
time
=
This
->
init_time
+
(
music_time
*
6510
);
EnterCriticalSection
(
&
This
->
safe
);
for
(
tempo
=
120
.
0
,
duration
=
tempo_time
=
0
;
music_time
>
0
;
tempo_time
+=
next
)
{
if
(
FAILED
(
hr
=
IDirectMusicPerformance_GetParam
(
iface
,
&
GUID_TempoParam
,
-
1
,
DMUS_SEG_ALLTRACKS
,
tempo_time
,
&
next
,
&
param
)))
break
;
if
(
!
next
)
next
=
music_time
;
else
next
=
min
(
next
,
music_time
);
if
(
param
.
mtTime
<=
0
)
tempo
=
param
.
dblTempo
;
duration
+=
(
600000000
.
0
*
next
)
/
(
tempo
*
DMUS_PPQ
);
music_time
-=
next
;
}
duration
+=
(
600000000
.
0
*
music_time
)
/
(
tempo
*
DMUS_PPQ
);
*
time
=
This
->
init_time
+
duration
;
LeaveCriticalSection
(
&
This
->
safe
);
return
S_OK
;
}
...
...
@@ -698,20 +718,38 @@ static HRESULT WINAPI performance_MusicToReferenceTime(IDirectMusicPerformance8
static
HRESULT
WINAPI
performance_ReferenceToMusicTime
(
IDirectMusicPerformance8
*
iface
,
REFERENCE_TIME
time
,
MUSIC_TIME
*
music_time
)
{
static
int
once
;
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
MUSIC_TIME
tempo_time
,
next
=
0
;
double
tempo
,
duration
,
step
;
DMUS_TEMPO_PARAM
param
;
HRESULT
hr
;
if
(
!
once
++
)
FIXME
(
"(%p, %I64d, %p): semi-stub
\n
"
,
This
,
time
,
music_time
);
else
TRACE
(
"(%p, %I64d, %p)
\n
"
,
This
,
time
,
music_time
);
TRACE
(
"(%p, %I64d, %p)
\n
"
,
This
,
time
,
music_time
);
if
(
!
music_time
)
return
E_POINTER
;
*
music_time
=
0
;
if
(
!
This
->
master_clock
)
return
DMUS_E_NO_MASTER_CLOCK
;
/* FIXME: This should be (time * DMUS_PPQ * tempo) / 60
* but it gives innacurate results */
*
music_time
=
(
time
-
This
->
init_time
)
/
6510
;
EnterCriticalSection
(
&
This
->
safe
);
duration
=
time
-
This
->
init_time
;
for
(
tempo
=
120
.
0
,
tempo_time
=
0
;
duration
>
0
;
tempo_time
+=
next
,
duration
-=
step
)
{
if
(
FAILED
(
hr
=
IDirectMusicPerformance_GetParam
(
iface
,
&
GUID_TempoParam
,
-
1
,
DMUS_SEG_ALLTRACKS
,
tempo_time
,
&
next
,
&
param
)))
break
;
if
(
param
.
mtTime
<=
0
)
tempo
=
param
.
dblTempo
;
step
=
(
600000000
.
0
*
next
)
/
(
tempo
*
DMUS_PPQ
);
if
(
!
next
||
duration
<
step
)
break
;
*
music_time
=
*
music_time
+
next
;
}
*
music_time
=
*
music_time
+
round
((
duration
*
tempo
*
DMUS_PPQ
)
/
600000000
.
0
);
LeaveCriticalSection
(
&
This
->
safe
);
return
S_OK
;
}
...
...
@@ -1085,13 +1123,26 @@ static HRESULT WINAPI performance_Invalidate(IDirectMusicPerformance8 *iface, MU
return
S_OK
;
}
static
HRESULT
WINAPI
performance_GetParam
(
IDirectMusicPerformance8
*
iface
,
REFGUID
rguidT
ype
,
DWORD
dwGroupBits
,
DWORD
dwIndex
,
MUSIC_TIME
mtTime
,
MUSIC_TIME
*
pmtNext
,
void
*
pP
aram
)
static
HRESULT
WINAPI
performance_GetParam
(
IDirectMusicPerformance8
*
iface
,
REFGUID
t
ype
,
DWORD
group
,
DWORD
index
,
MUSIC_TIME
music_time
,
MUSIC_TIME
*
next_time
,
void
*
p
aram
)
{
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
HRESULT
hr
;
FIXME
(
"(%p, %s, %ld, %ld, %ld, %p, %p): stub
\n
"
,
This
,
debugstr_dmguid
(
rguidType
),
dwGroupBits
,
dwIndex
,
mtTime
,
pmtNext
,
pParam
);
return
S_OK
;
TRACE
(
"(%p, %s, %ld, %ld, %ld, %p, %p)
\n
"
,
This
,
debugstr_dmguid
(
type
),
group
,
index
,
music_time
,
next_time
,
param
);
if
(
next_time
)
*
next_time
=
0
;
if
(
!
This
->
control_segment
)
hr
=
DMUS_E_NOT_FOUND
;
else
hr
=
IDirectMusicSegment_GetParam
(
This
->
control_segment
,
type
,
group
,
index
,
music_time
,
next_time
,
param
);
if
(
FAILED
(
hr
))
{
if
(
!
This
->
primary_segment
)
hr
=
DMUS_E_NOT_FOUND
;
else
hr
=
IDirectMusicSegment_GetParam
(
This
->
primary_segment
,
type
,
group
,
index
,
music_time
,
next_time
,
param
);
}
return
hr
;
}
static
HRESULT
WINAPI
performance_SetParam
(
IDirectMusicPerformance8
*
iface
,
REFGUID
rguidType
,
...
...
dlls/dmime/tests/dmime.c
View file @
18a81b3c
...
...
@@ -2735,11 +2735,11 @@ static void test_performance_time(void)
time
=
0xdeadbeef
;
hr
=
IDirectMusicPerformance_MusicToReferenceTime
(
performance
,
1000
,
&
time
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
todo_wine
check_music_time
(
time
-
init_time
,
scale_music_time
(
1000
,
120
));
check_music_time
(
time
-
init_time
,
scale_music_time
(
1000
,
120
));
time
=
0xdeadbeef
;
hr
=
IDirectMusicPerformance_MusicToReferenceTime
(
performance
,
2000
,
&
time
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
todo_wine
check_music_time
(
time
-
init_time
,
scale_music_time
(
2000
,
120
));
check_music_time
(
time
-
init_time
,
scale_music_time
(
2000
,
120
));
music_time
=
0xdeadbeef
;
hr
=
IDirectMusicPerformance_ReferenceToMusicTime
(
performance
,
init_time
,
&
music_time
);
...
...
@@ -4098,19 +4098,19 @@ static void test_tempo_track_play(void)
time
=
0xdeadbeef
;
hr
=
IDirectMusicPerformance_MusicToReferenceTime
(
performance
,
100
,
&
time
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
todo_wine
check_music_time
(
time
-
init_time
,
scale_music_time
(
100
,
120
));
check_music_time
(
time
-
init_time
,
scale_music_time
(
100
,
120
));
time
=
0xdeadbeef
;
hr
=
IDirectMusicPerformance_MusicToReferenceTime
(
performance
,
150
,
&
time
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
todo_wine
check_music_time
(
time
-
init_time
,
scale_music_time
(
100
,
120
)
+
scale_music_time
(
50
,
80
));
check_music_time
(
time
-
init_time
,
scale_music_time
(
100
,
120
)
+
scale_music_time
(
50
,
80
));
time
=
0xdeadbeef
;
hr
=
IDirectMusicPerformance_MusicToReferenceTime
(
performance
,
200
,
&
time
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
todo_wine
check_music_time
(
time
-
init_time
,
scale_music_time
(
100
,
120
)
+
scale_music_time
(
100
,
80
));
check_music_time
(
time
-
init_time
,
scale_music_time
(
100
,
120
)
+
scale_music_time
(
100
,
80
));
time
=
0xdeadbeef
;
hr
=
IDirectMusicPerformance_MusicToReferenceTime
(
performance
,
400
,
&
time
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
todo_wine
check_music_time
(
time
-
init_time
,
scale_music_time
(
100
,
120
)
+
scale_music_time
(
200
,
80
)
+
scale_music_time
(
100
,
20
));
check_music_time
(
time
-
init_time
,
scale_music_time
(
100
,
120
)
+
scale_music_time
(
200
,
80
)
+
scale_music_time
(
100
,
20
));
music_time
=
0xdeadbeef
;
hr
=
IDirectMusicPerformance_ReferenceToMusicTime
(
performance
,
init_time
,
&
music_time
);
...
...
@@ -4120,15 +4120,15 @@ static void test_tempo_track_play(void)
time
=
scale_music_time
(
100
,
120
)
+
scale_music_time
(
50
,
80
);
hr
=
IDirectMusicPerformance_ReferenceToMusicTime
(
performance
,
init_time
+
time
,
&
music_time
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
todo_wine
ok
(
music_time
==
150
,
"got %ld
\n
"
,
music_time
);
ok
(
music_time
==
150
,
"got %ld
\n
"
,
music_time
);
music_time
=
0xdeadbeef
;
time
=
scale_music_time
(
100
,
120
)
+
scale_music_time
(
200
,
80
)
+
scale_music_time
(
100
,
20
);
hr
=
IDirectMusicPerformance_ReferenceToMusicTime
(
performance
,
init_time
+
time
,
&
music_time
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
todo_wine
ok
(
music_time
==
400
,
"got %ld
\n
"
,
music_time
);
ok
(
music_time
==
400
,
"got %ld
\n
"
,
music_time
);
ret
=
test_tool_wait_message
(
tool
,
5
00
,
(
DMUS_PMSG
**
)
&
tempo
);
ret
=
test_tool_wait_message
(
tool
,
20
00
,
(
DMUS_PMSG
**
)
&
tempo
);
ok
(
!
ret
,
"got %#lx
\n
"
,
ret
);
todo_wine
ok
(
tempo
->
dwType
==
DMUS_PMSGT_TEMPO
,
"got %#lx
\n
"
,
tempo
->
dwType
);
if
(
tempo
->
dwType
!=
DMUS_PMSGT_TEMPO
)
goto
skip_tests
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment