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
7bbd4be5
Commit
7bbd4be5
authored
Oct 10, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Oct 11, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dmime: Create a wave track when loading a segment from a .wav.
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=9027
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=34751
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=45135
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=48220
parent
15c4c02e
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
94 additions
and
74 deletions
+94
-74
Makefile.in
dlls/dmime/Makefile.in
+1
-0
dmime_private.h
dlls/dmime/dmime_private.h
+3
-0
segment.c
dlls/dmime/segment.c
+42
-69
dmime.c
dlls/dmime/tests/dmime.c
+1
-1
wavetrack.c
dlls/dmime/wavetrack.c
+39
-4
dmusic_wave.h
dlls/dmusic/dmusic_wave.h
+1
-0
wave.c
dlls/dmusic/wave.c
+7
-0
No files found.
dlls/dmime/Makefile.in
View file @
7bbd4be5
...
...
@@ -18,6 +18,7 @@ C_SRCS = \
sysextrack.c
\
tempotrack.c
\
timesigtrack.c
\
wave.c
\
wavetrack.c
IDL_SRCS
=
dmime.idl
...
...
dlls/dmime/dmime_private.h
View file @
7bbd4be5
...
...
@@ -77,6 +77,9 @@ extern HRESULT segment_state_create(IDirectMusicSegment *segment, MUSIC_TIME sta
extern
HRESULT
segment_state_play
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance
*
performance
);
extern
HRESULT
segment_state_end_play
(
IDirectMusicSegmentState
*
iface
);
extern
HRESULT
wave_track_create_from_chunk
(
IStream
*
stream
,
struct
chunk_entry
*
parent
,
IDirectMusicTrack8
**
ret_iface
);
/*****************************************************************************
* Auxiliary definitions
*/
...
...
dlls/dmime/segment.c
View file @
7bbd4be5
...
...
@@ -741,13 +741,17 @@ static inline void dump_segment_header(DMUS_IO_SEGMENT_HEADER *h, DWORD size)
}
}
static
HRESULT
parse_
segment_form
(
struct
segment
*
This
,
IStream
*
stream
,
const
struct
chunk_entry
*
riff
)
static
HRESULT
parse_
dmsg_chunk
(
struct
segment
*
This
,
IStream
*
stream
,
const
struct
chunk_entry
*
riff
)
{
struct
chunk_entry
chunk
=
{.
parent
=
riff
};
HRESULT
hr
;
TRACE
(
"Parsing segment form in %p: %s
\n
"
,
stream
,
debugstr_chunk
(
riff
));
if
(
FAILED
(
hr
=
dmobj_parsedescriptor
(
stream
,
riff
,
&
This
->
dmobj
.
desc
,
DMUS_OBJ_NAME
|
DMUS_OBJ_CATEGORY
))
||
FAILED
(
hr
=
stream_reset_chunk_data
(
stream
,
riff
)))
return
hr
;
while
((
hr
=
stream_next_chunk
(
stream
,
&
chunk
))
==
S_OK
)
{
switch
(
chunk
.
id
)
{
case
DMUS_FOURCC_SEGMENT_CHUNK
:
...
...
@@ -786,89 +790,58 @@ static inline struct segment *impl_from_IPersistStream(IPersistStream *iface)
return
CONTAINING_RECORD
(
iface
,
struct
segment
,
dmobj
.
IPersistStream_iface
);
}
static
HRESULT
parse_wave_form
(
struct
segment
*
This
,
IStream
*
stream
,
const
struct
chunk_entry
*
riff
)
static
HRESULT
WINAPI
segment_persist_stream_Load
(
IPersistStream
*
iface
,
IStream
*
stream
)
{
struct
segment
*
This
=
impl_from_IPersistStream
(
iface
);
struct
chunk_entry
chunk
=
{
0
};
HRESULT
hr
;
struct
chunk_entry
chunk
=
{.
parent
=
riff
};
TRACE
(
"
Parsing segment wave in %p: %s
\n
"
,
stream
,
debugstr_chunk
(
riff
)
);
TRACE
(
"
(%p, %p): Loading
\n
"
,
This
,
stream
);
while
((
hr
=
stream_next_chunk
(
stream
,
&
chunk
))
==
S_OK
)
{
switch
(
chunk
.
id
)
{
case
mmioFOURCC
(
'f'
,
'm'
,
't'
,
' '
):
{
if
(
FAILED
(
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
&
This
->
wave_format
,
sizeof
(
This
->
wave_format
)))
)
return
hr
;
TRACE
(
"Wave Format tag %d
\n
"
,
This
->
wave_format
.
wf
.
wFormatTag
);
break
;
}
case
mmioFOURCC
(
'd'
,
'a'
,
't'
,
'a'
):
{
TRACE
(
"Wave Data size %lu
\n
"
,
chunk
.
size
);
if
(
This
->
wave_data
)
ERR
(
"Multiple data streams detected
\n
"
);
This
->
wave_data
=
malloc
(
chunk
.
size
);
This
->
data_size
=
chunk
.
size
;
if
(
!
This
->
wave_data
)
return
E_OUTOFMEMORY
;
if
(
FAILED
(
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
This
->
wave_data
,
chunk
.
size
)))
return
hr
;
break
;
}
case
FOURCC_LIST
:
{
FIXME
(
"Skipping LIST tag
\n
"
);
break
;
}
case
mmioFOURCC
(
'I'
,
'S'
,
'F'
,
'T'
):
{
FIXME
(
"Skipping ISFT tag
\n
"
);
break
;
}
case
mmioFOURCC
(
'f'
,
'a'
,
'c'
,
't'
):
{
FIXME
(
"Skipping fact tag
\n
"
);
break
;
}
}
}
if
(
!
stream
)
return
E_POINTER
;
return
SUCCEEDED
(
hr
)
?
S_OK
:
hr
;
}
if
((
hr
=
stream_get_chunk
(
stream
,
&
chunk
))
==
S_OK
)
{
switch
(
MAKE_IDTYPE
(
chunk
.
id
,
chunk
.
type
))
{
case
MAKE_IDTYPE
(
FOURCC_RIFF
,
DMUS_FOURCC_SEGMENT_FORM
):
hr
=
parse_dmsg_chunk
(
This
,
stream
,
&
chunk
);
break
;
static
HRESULT
WINAPI
segment_persist_stream_Load
(
IPersistStream
*
iface
,
IStream
*
stream
)
{
struct
segment
*
This
=
impl_from_IPersistStream
(
iface
);
struct
chunk_entry
riff
=
{
0
};
HRESULT
hr
;
case
mmioFOURCC
(
'M'
,
'T'
,
'h'
,
'd'
):
FIXME
(
"MIDI file loading not supported
\n
"
);
break
;
TRACE
(
"(%p, %p): Loading
\n
"
,
This
,
stream
);
case
MAKE_IDTYPE
(
FOURCC_RIFF
,
mmioFOURCC
(
'W'
,
'A'
,
'V'
,
'E'
)):
{
IDirectMusicTrack8
*
track
;
HRESULT
hr
;
if
(
!
stream
)
return
E_POINTER
;
TRACE
(
"Loading segment %p from wave file
\n
"
,
This
);
if
(
stream_get_chunk
(
stream
,
&
riff
)
!=
S_OK
||
(
riff
.
id
!=
FOURCC_RIFF
&&
riff
.
id
!=
mmioFOURCC
(
'M'
,
'T'
,
'h'
,
'd'
)))
return
DMUS_E_UNSUPPORTED_STREAM
;
stream_reset_chunk_start
(
stream
,
&
riff
);
This
->
header
.
mtLength
=
1
;
if
(
FAILED
(
hr
=
wave_track_create_from_chunk
(
stream
,
&
chunk
,
&
track
)))
break
;
hr
=
segment_append_track
(
This
,
(
IDirectMusicTrack
*
)
track
,
1
,
0
);
break
;
}
if
(
riff
.
id
==
mmioFOURCC
(
'M'
,
'T'
,
'h'
,
'd'
))
{
FIXME
(
"MIDI file loading not supported
\n
"
);
return
S_OK
;
default:
WARN
(
"Invalid segment chunk %s %s
\n
"
,
debugstr_fourcc
(
chunk
.
id
),
debugstr_fourcc
(
chunk
.
type
));
hr
=
DMUS_E_UNSUPPORTED_STREAM
;
break
;
}
}
hr
=
IDirectMusicObject_ParseDescriptor
(
&
This
->
dmobj
.
IDirectMusicObject_iface
,
stream
,
&
This
->
dmobj
.
desc
);
if
(
FAILED
(
hr
))
return
hr
;
stream_reset_chunk_data
(
stream
,
&
riff
);
if
(
riff
.
type
==
DMUS_FOURCC_SEGMENT_FORM
)
hr
=
parse_segment_form
(
This
,
stream
,
&
riff
);
else
if
(
riff
.
type
==
mmioFOURCC
(
'W'
,
'A'
,
'V'
,
'E'
))
hr
=
parse_wave_form
(
This
,
stream
,
&
riff
);
else
{
FIXME
(
"Unknown type %s
\n
"
,
debugstr_chunk
(
&
riff
));
hr
=
S_OK
;
{
WARN
(
"Failed to load segment from stream %p, hr %#lx
\n
"
,
stream
,
hr
);
return
DMUS_E_UNSUPPORTED_STREAM
;
}
return
hr
;
This
->
dmobj
.
desc
.
guidClass
=
CLSID_DirectMusicSegment
;
This
->
dmobj
.
desc
.
dwValidData
|=
DMUS_OBJ_CLASS
;
return
S_OK
;
}
static
const
IPersistStreamVtbl
segment_persist_stream_vtbl
=
...
...
dlls/dmime/tests/dmime.c
View file @
7bbd4be5
...
...
@@ -3279,7 +3279,7 @@ static void test_wave_pmsg(void)
length
=
0xdeadbeef
;
hr
=
IDirectMusicSegment_GetLength
(
segment
,
&
length
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
todo_wine
ok
(
length
==
1
,
"got %lu
\n
"
,
length
);
ok
(
length
==
1
,
"got %lu
\n
"
,
length
);
/* without Download, no DMUS_PMSGT_WAVE is sent */
...
...
dlls/dmime/wavetrack.c
View file @
7bbd4be5
...
...
@@ -17,13 +17,14 @@
*/
#include "dmime_private.h"
#include "dmusic_wave.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
dmime
);
struct
wave_item
{
struct
list
entry
;
DMUS_IO_WAVE_ITEM_HEADER
header
;
I
DirectMusicObject
*
object
;
I
Unknown
*
object
;
};
struct
wave_part
{
...
...
@@ -100,8 +101,7 @@ static ULONG WINAPI wave_track_Release(IDirectMusicTrack8 *iface)
list_remove
(
&
part
->
entry
);
LIST_FOR_EACH_ENTRY_SAFE
(
item
,
item2
,
&
part
->
items
,
struct
wave_item
,
entry
)
{
list_remove
(
&
item
->
entry
);
if
(
item
->
object
)
IDirectMusicObject_Release
(
item
->
object
);
if
(
item
->
object
)
IUnknown_Release
(
item
->
object
);
free
(
item
);
}
free
(
part
);
...
...
@@ -355,7 +355,7 @@ static HRESULT parse_wave_item(struct wave_part *part, IStream *stream, struct c
hr
=
DMUS_E_UNSUPPORTED_STREAM
;
goto
error
;
}
if
(
FAILED
(
hr
=
dmobj_parsereference
(
stream
,
&
chunk
,
&
item
->
object
)))
if
(
FAILED
(
hr
=
dmobj_parsereference
(
stream
,
&
chunk
,
(
IDirectMusicObject
**
)
&
item
->
object
)))
goto
error
;
list_add_tail
(
&
part
->
items
,
&
item
->
entry
);
...
...
@@ -484,3 +484,38 @@ HRESULT create_dmwavetrack(REFIID lpcGUID, void **ppobj)
return
hr
;
}
HRESULT
wave_track_create_from_chunk
(
IStream
*
stream
,
struct
chunk_entry
*
parent
,
IDirectMusicTrack8
**
ret_iface
)
{
IDirectMusicTrack8
*
iface
;
struct
wave_track
*
This
;
struct
wave_item
*
item
;
struct
wave_part
*
part
;
HRESULT
hr
;
if
(
FAILED
(
hr
=
create_dmwavetrack
(
&
IID_IDirectMusicTrack8
,
(
void
**
)
&
iface
)))
return
hr
;
This
=
impl_from_IDirectMusicTrack8
(
iface
);
if
(
!
(
part
=
calloc
(
1
,
sizeof
(
*
part
))))
{
IDirectMusicTrack8_Release
(
iface
);
return
E_OUTOFMEMORY
;
}
list_init
(
&
part
->
items
);
list_add_tail
(
&
This
->
parts
,
&
part
->
entry
);
if
(
!
(
item
=
calloc
(
1
,
sizeof
(
*
item
)))
||
FAILED
(
hr
=
wave_create_from_chunk
(
stream
,
parent
,
&
item
->
object
)))
{
IDirectMusicTrack8_Release
(
iface
);
free
(
item
);
return
hr
;
}
if
(
FAILED
(
hr
=
wave_get_duration
(
item
->
object
,
&
item
->
header
.
rtDuration
)))
WARN
(
"Failed to get wave duration, hr %#lx
\n
"
,
hr
);
list_add_tail
(
&
part
->
items
,
&
item
->
entry
);
*
ret_iface
=
iface
;
return
S_OK
;
}
dlls/dmusic/dmusic_wave.h
View file @
7bbd4be5
...
...
@@ -32,3 +32,4 @@ struct chunk_entry;
extern
HRESULT
wave_create_from_soundfont
(
struct
soundfont
*
soundfont
,
UINT
index
,
IUnknown
**
out
);
extern
HRESULT
wave_create_from_chunk
(
IStream
*
stream
,
struct
chunk_entry
*
parent
,
IUnknown
**
out
);
extern
HRESULT
wave_download_to_port
(
IUnknown
*
iface
,
IDirectMusicPortDownload
*
port
,
DWORD
*
id
);
extern
HRESULT
wave_get_duration
(
IUnknown
*
iface
,
REFERENCE_TIME
*
duration
);
dlls/dmusic/wave.c
View file @
7bbd4be5
...
...
@@ -338,3 +338,10 @@ HRESULT wave_download_to_port(IUnknown *iface, IDirectMusicPortDownload *port, D
IDirectMusicDownload_Release
(
download
);
return
hr
;
}
HRESULT
wave_get_duration
(
IUnknown
*
iface
,
REFERENCE_TIME
*
duration
)
{
struct
wave
*
This
=
impl_from_IUnknown
(
iface
);
*
duration
=
(
REFERENCE_TIME
)
This
->
data_size
*
10000000
/
This
->
format
->
nAvgBytesPerSec
;
return
S_OK
;
}
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