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
82d1794c
Commit
82d1794c
authored
Sep 15, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Sep 18, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dmusic: Parse collection wave lists.
parent
2f5608ef
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
228 additions
and
5 deletions
+228
-5
Makefile.in
dlls/dmusic/Makefile.in
+2
-1
collection.c
dlls/dmusic/collection.c
+10
-4
dmusic_private.h
dlls/dmusic/dmusic_private.h
+2
-0
wave.c
dlls/dmusic/wave.c
+214
-0
No files found.
dlls/dmusic/Makefile.in
View file @
82d1794c
...
...
@@ -10,7 +10,8 @@ C_SRCS = \
dmusic_main.c
\
download.c
\
instrument.c
\
port.c
port.c
\
wave.c
IDL_SRCS
=
dmusic.idl
...
...
dlls/dmusic/collection.c
View file @
82d1794c
...
...
@@ -40,6 +40,7 @@ C_ASSERT(sizeof(struct pool) == offsetof(struct pool, cues[0]));
struct
wave_entry
{
struct
list
entry
;
IUnknown
*
wave
;
DWORD
offset
;
};
...
...
@@ -123,6 +124,7 @@ static ULONG WINAPI collection_Release(IDirectMusicCollection *iface)
LIST_FOR_EACH_ENTRY_SAFE
(
wave_entry
,
next
,
&
This
->
waves
,
struct
wave_entry
,
entry
)
{
list_remove
(
&
wave_entry
->
entry
);
IDirectMusicInstrument_Release
(
wave_entry
->
wave
);
free
(
wave_entry
);
}
...
...
@@ -227,8 +229,12 @@ static HRESULT parse_wvpl_list(struct collection *This, IStream *stream, struct
{
case
MAKE_IDTYPE
(
FOURCC_LIST
,
FOURCC_wave
):
if
(
!
(
entry
=
malloc
(
sizeof
(
*
entry
))))
return
E_OUTOFMEMORY
;
entry
->
offset
=
chunk
.
offset
.
QuadPart
-
parent
->
offset
.
QuadPart
-
12
;
list_add_tail
(
&
This
->
waves
,
&
entry
->
entry
);
if
(
FAILED
(
hr
=
wave_create_from_chunk
(
stream
,
&
chunk
,
&
entry
->
wave
)))
free
(
entry
);
else
{
entry
->
offset
=
chunk
.
offset
.
QuadPart
-
parent
->
offset
.
QuadPart
-
12
;
list_add_tail
(
&
This
->
waves
,
&
entry
->
entry
);
}
break
;
default:
...
...
@@ -397,13 +403,13 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface, IStream *str
i
++
;
}
TRACE
(
" - cues:
size %lu
\n
"
,
This
->
pool
->
table
.
cbSize
);
TRACE
(
" - cues:
\n
"
);
for
(
i
=
0
;
i
<
This
->
pool
->
table
.
cCues
;
i
++
)
TRACE
(
" - index: %u, offset: %lu
\n
"
,
i
,
This
->
pool
->
cues
[
i
].
ulOffset
);
TRACE
(
" - waves:
\n
"
);
LIST_FOR_EACH_ENTRY
(
wave_entry
,
&
This
->
waves
,
struct
wave_entry
,
entry
)
TRACE
(
" - offset: %lu
\n
"
,
wave_entry
->
offset
);
TRACE
(
" - offset: %lu
, wave %p
\n
"
,
wave_entry
->
offset
,
wave_entry
->
wave
);
}
stream_skip_chunk
(
stream
,
&
chunk
);
...
...
dlls/dmusic/dmusic_private.h
View file @
82d1794c
...
...
@@ -92,6 +92,8 @@ extern HRESULT instrument_download_to_port(IDirectMusicInstrument *iface, IDirec
IDirectMusicDownloadedInstrument
**
downloaded
);
extern
HRESULT
instrument_unload_from_port
(
IDirectMusicDownloadedInstrument
*
iface
,
IDirectMusicPortDownload
*
port
);
extern
HRESULT
wave_create_from_chunk
(
IStream
*
stream
,
struct
chunk_entry
*
parent
,
IUnknown
**
out
);
/*****************************************************************************
* IDirectMusic8Impl implementation structure
*/
...
...
dlls/dmusic/wave.c
0 → 100644
View file @
82d1794c
/*
* Copyright 2023 Rémi Bernon for CodeWeavers
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "dmusic_private.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
dmusic
);
struct
sample
{
WSMPL
head
;
WLOOP
loops
[];
};
C_ASSERT
(
sizeof
(
struct
sample
)
==
offsetof
(
struct
sample
,
loops
[
0
]));
struct
wave
{
IUnknown
IUnknown_iface
;
LONG
ref
;
struct
sample
*
sample
;
WAVEFORMATEX
*
format
;
UINT
data_size
;
void
*
data
;
};
static
inline
struct
wave
*
impl_from_IUnknown
(
IUnknown
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
wave
,
IUnknown_iface
);
}
static
HRESULT
WINAPI
wave_QueryInterface
(
IUnknown
*
iface
,
REFIID
riid
,
void
**
ret_iface
)
{
struct
wave
*
This
=
impl_from_IUnknown
(
iface
);
TRACE
(
"(%p, %s, %p)
\n
"
,
This
,
debugstr_dmguid
(
riid
),
ret_iface
);
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
ret_iface
=
&
This
->
IUnknown_iface
;
IUnknown_AddRef
(
&
This
->
IUnknown_iface
);
return
S_OK
;
}
WARN
(
"(%p, %s, %p): not found
\n
"
,
This
,
debugstr_dmguid
(
riid
),
ret_iface
);
*
ret_iface
=
NULL
;
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
wave_AddRef
(
IUnknown
*
iface
)
{
struct
wave
*
This
=
impl_from_IUnknown
(
iface
);
LONG
ref
=
InterlockedIncrement
(
&
This
->
ref
);
TRACE
(
"(%p) ref=%ld
\n
"
,
This
,
ref
);
return
ref
;
}
static
ULONG
WINAPI
wave_Release
(
IUnknown
*
iface
)
{
struct
wave
*
This
=
impl_from_IUnknown
(
iface
);
LONG
ref
=
InterlockedDecrement
(
&
This
->
ref
);
TRACE
(
"(%p) ref=%ld
\n
"
,
This
,
ref
);
if
(
!
ref
)
{
free
(
This
->
format
);
free
(
This
->
data
);
free
(
This
->
sample
);
free
(
This
);
}
return
ref
;
}
static
const
IUnknownVtbl
unknown_vtbl
=
{
wave_QueryInterface
,
wave_AddRef
,
wave_Release
,
};
static
HRESULT
wave_create
(
IUnknown
**
ret_iface
)
{
struct
wave
*
obj
;
if
(
!
(
obj
=
calloc
(
1
,
sizeof
(
*
obj
))))
return
E_OUTOFMEMORY
;
obj
->
IUnknown_iface
.
lpVtbl
=
&
unknown_vtbl
;
obj
->
ref
=
1
;
*
ret_iface
=
&
obj
->
IUnknown_iface
;
return
S_OK
;
}
static
HRESULT
parse_wsmp_chunk
(
struct
wave
*
This
,
IStream
*
stream
,
struct
chunk_entry
*
chunk
)
{
struct
sample
*
sample
;
WSMPL
wsmpl
;
HRESULT
hr
;
UINT
size
;
if
(
chunk
->
size
<
sizeof
(
wsmpl
))
return
E_INVALIDARG
;
if
(
FAILED
(
hr
=
stream_read
(
stream
,
&
wsmpl
,
sizeof
(
wsmpl
))))
return
hr
;
if
(
chunk
->
size
!=
wsmpl
.
cbSize
+
sizeof
(
WLOOP
)
*
wsmpl
.
cSampleLoops
)
return
E_INVALIDARG
;
if
(
wsmpl
.
cbSize
!=
sizeof
(
wsmpl
))
return
E_INVALIDARG
;
if
(
wsmpl
.
cSampleLoops
>
1
)
FIXME
(
"Not implemented: found more than one wave loop
\n
"
);
size
=
offsetof
(
struct
sample
,
loops
[
wsmpl
.
cSampleLoops
]);
if
(
!
(
sample
=
malloc
(
size
)))
return
E_OUTOFMEMORY
;
sample
->
head
=
wsmpl
;
size
=
sizeof
(
WLOOP
)
*
wsmpl
.
cSampleLoops
;
if
(
FAILED
(
hr
=
stream_read
(
stream
,
sample
->
loops
,
size
)))
free
(
sample
);
else
This
->
sample
=
sample
;
return
hr
;
}
static
HRESULT
parse_wave_chunk
(
struct
wave
*
This
,
IStream
*
stream
,
struct
chunk_entry
*
parent
)
{
struct
chunk_entry
chunk
=
{.
parent
=
parent
};
HRESULT
hr
;
while
((
hr
=
stream_next_chunk
(
stream
,
&
chunk
))
==
S_OK
)
{
switch
(
MAKE_IDTYPE
(
chunk
.
id
,
chunk
.
type
))
{
case
mmioFOURCC
(
'f'
,
'm'
,
't'
,
' '
):
if
(
!
(
This
->
format
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
This
->
format
,
chunk
.
size
);
break
;
case
mmioFOURCC
(
'd'
,
'a'
,
't'
,
'a'
):
if
(
!
(
This
->
data
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
This
->
data
,
chunk
.
size
);
if
(
SUCCEEDED
(
hr
))
This
->
data_size
=
chunk
.
size
;
break
;
case
FOURCC_WSMP
:
hr
=
parse_wsmp_chunk
(
This
,
stream
,
&
chunk
);
break
;
default:
FIXME
(
"Ignoring chunk %s %s
\n
"
,
debugstr_fourcc
(
chunk
.
id
),
debugstr_fourcc
(
chunk
.
type
));
break
;
}
if
(
FAILED
(
hr
))
break
;
}
return
hr
;
}
HRESULT
wave_create_from_chunk
(
IStream
*
stream
,
struct
chunk_entry
*
parent
,
IUnknown
**
ret_iface
)
{
struct
wave
*
This
;
IUnknown
*
iface
;
HRESULT
hr
;
TRACE
(
"(%p, %p, %p)
\n
"
,
stream
,
parent
,
ret_iface
);
if
(
FAILED
(
hr
=
wave_create
(
&
iface
)))
return
hr
;
This
=
impl_from_IUnknown
(
iface
);
if
(
FAILED
(
hr
=
parse_wave_chunk
(
This
,
stream
,
parent
)))
{
IUnknown_Release
(
iface
);
return
DMUS_E_UNSUPPORTED_STREAM
;
}
if
(
TRACE_ON
(
dmusic
))
{
UINT
i
;
TRACE
(
"*** Created DirectMusicWave %p
\n
"
,
This
);
TRACE
(
" - format: %p
\n
"
,
This
->
format
);
if
(
This
->
format
)
{
TRACE
(
" - wFormatTag: %u
\n
"
,
This
->
format
->
wFormatTag
);
TRACE
(
" - nChannels: %u
\n
"
,
This
->
format
->
nChannels
);
TRACE
(
" - nSamplesPerSec: %lu
\n
"
,
This
->
format
->
nSamplesPerSec
);
TRACE
(
" - nAvgBytesPerSec: %lu
\n
"
,
This
->
format
->
nAvgBytesPerSec
);
TRACE
(
" - nBlockAlign: %u
\n
"
,
This
->
format
->
nBlockAlign
);
TRACE
(
" - wBitsPerSample: %u
\n
"
,
This
->
format
->
wBitsPerSample
);
TRACE
(
" - cbSize: %u
\n
"
,
This
->
format
->
cbSize
);
}
TRACE
(
" - sample: {size: %lu, unity_note: %u, fine_tune: %d, attenuation: %ld, options: %#lx, loops: %lu}
\n
"
,
This
->
sample
->
head
.
cbSize
,
This
->
sample
->
head
.
usUnityNote
,
This
->
sample
->
head
.
sFineTune
,
This
->
sample
->
head
.
lAttenuation
,
This
->
sample
->
head
.
fulOptions
,
This
->
sample
->
head
.
cSampleLoops
);
for
(
i
=
0
;
i
<
This
->
sample
->
head
.
cSampleLoops
;
i
++
)
TRACE
(
" - loops[%u]: {size: %lu, type: %lu, start: %lu, length: %lu}
\n
"
,
i
,
This
->
sample
->
loops
[
i
].
cbSize
,
This
->
sample
->
loops
[
i
].
ulType
,
This
->
sample
->
loops
[
i
].
ulStart
,
This
->
sample
->
loops
[
i
].
ulLength
);
}
*
ret_iface
=
iface
;
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