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
b733a46a
Commit
b733a46a
authored
Sep 21, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Sep 29, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dmusic: Implement SoundFont2 collection parsing.
parent
182338ba
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
574 additions
and
6 deletions
+574
-6
dmime.c
dlls/dmime/tests/dmime.c
+1
-1
collection.c
dlls/dmusic/collection.c
+247
-2
soundfont.h
dlls/dmusic/soundfont.h
+323
-0
dmusic.c
dlls/dmusic/tests/dmusic.c
+3
-3
No files found.
dlls/dmime/tests/dmime.c
View file @
b733a46a
...
...
@@ -3546,7 +3546,7 @@ static void test_band_track_play(void)
&
IID_IDirectMusicLoader8
,
(
void
**
)
&
loader
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
IDirectMusicLoader_SetObject
(
loader
,
&
desc
);
todo_wine
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
test_loader_stream_create
(
stream
,
loader
,
&
loader_stream
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
...
...
dlls/dmusic/collection.c
View file @
b733a46a
...
...
@@ -19,6 +19,7 @@
*/
#include "dmusic_private.h"
#include "soundfont.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
dmusic
);
...
...
@@ -353,6 +354,246 @@ static HRESULT parse_dls_chunk(struct collection *This, IStream *stream, struct
return
hr
;
}
static
HRESULT
parse_sdta_list
(
struct
collection
*
This
,
IStream
*
stream
,
struct
chunk_entry
*
parent
,
struct
soundfont
*
soundfont
)
{
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
(
's'
,
'm'
,
'p'
,
'l'
):
if
(
soundfont
->
sdta
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
sdta
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
sdta
,
chunk
.
size
);
break
;
default:
FIXME
(
"Skipping unknown chunk %s %s
\n
"
,
debugstr_fourcc
(
chunk
.
id
),
debugstr_fourcc
(
chunk
.
type
));
break
;
}
if
(
FAILED
(
hr
))
break
;
}
return
hr
;
}
static
HRESULT
parse_pdta_list
(
struct
collection
*
This
,
IStream
*
stream
,
struct
chunk_entry
*
parent
,
struct
soundfont
*
soundfont
)
{
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
(
'p'
,
'h'
,
'd'
,
'r'
):
if
(
soundfont
->
phdr
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
phdr
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
phdr
,
chunk
.
size
);
soundfont
->
preset_count
=
chunk
.
size
/
sizeof
(
*
soundfont
->
phdr
)
-
1
;
break
;
case
mmioFOURCC
(
'p'
,
'b'
,
'a'
,
'g'
):
if
(
soundfont
->
pbag
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
pbag
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
pbag
,
chunk
.
size
);
break
;
case
mmioFOURCC
(
'p'
,
'm'
,
'o'
,
'd'
):
if
(
soundfont
->
pmod
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
pmod
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
pmod
,
chunk
.
size
);
break
;
case
mmioFOURCC
(
'p'
,
'g'
,
'e'
,
'n'
):
if
(
soundfont
->
pgen
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
pgen
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
pgen
,
chunk
.
size
);
break
;
case
mmioFOURCC
(
'i'
,
'n'
,
's'
,
't'
):
if
(
soundfont
->
inst
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
inst
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
inst
,
chunk
.
size
);
soundfont
->
instrument_count
=
chunk
.
size
/
sizeof
(
*
soundfont
->
inst
)
-
1
;
break
;
case
mmioFOURCC
(
'i'
,
'b'
,
'a'
,
'g'
):
if
(
soundfont
->
ibag
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
ibag
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
ibag
,
chunk
.
size
);
break
;
case
mmioFOURCC
(
'i'
,
'm'
,
'o'
,
'd'
):
if
(
soundfont
->
imod
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
imod
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
imod
,
chunk
.
size
);
break
;
case
mmioFOURCC
(
'i'
,
'g'
,
'e'
,
'n'
):
if
(
soundfont
->
igen
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
igen
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
igen
,
chunk
.
size
);
break
;
case
mmioFOURCC
(
's'
,
'h'
,
'd'
,
'r'
):
if
(
soundfont
->
shdr
)
return
E_INVALIDARG
;
if
(
!
(
soundfont
->
shdr
=
malloc
(
chunk
.
size
)))
return
E_OUTOFMEMORY
;
hr
=
stream_chunk_get_data
(
stream
,
&
chunk
,
soundfont
->
shdr
,
chunk
.
size
);
soundfont
->
sample_count
=
chunk
.
size
/
sizeof
(
*
soundfont
->
shdr
)
-
1
;
break
;
default:
FIXME
(
"Skipping unknown chunk %s %s
\n
"
,
debugstr_fourcc
(
chunk
.
id
),
debugstr_fourcc
(
chunk
.
type
));
break
;
}
if
(
FAILED
(
hr
))
break
;
}
return
hr
;
}
static
HRESULT
parse_sfbk_chunk
(
struct
collection
*
This
,
IStream
*
stream
,
struct
chunk_entry
*
parent
)
{
struct
chunk_entry
chunk
=
{.
parent
=
parent
};
struct
soundfont
soundfont
=
{
0
};
UINT
i
,
j
,
k
;
HRESULT
hr
;
if
(
FAILED
(
hr
=
dmobj_parsedescriptor
(
stream
,
parent
,
&
This
->
dmobj
.
desc
,
DMUS_OBJ_NAME_INFO
|
DMUS_OBJ_VERSION
|
DMUS_OBJ_OBJECT
|
DMUS_OBJ_GUID_DLID
))
||
FAILED
(
hr
=
stream_reset_chunk_data
(
stream
,
parent
)))
return
hr
;
while
((
hr
=
stream_next_chunk
(
stream
,
&
chunk
))
==
S_OK
)
{
switch
(
MAKE_IDTYPE
(
chunk
.
id
,
chunk
.
type
))
{
case
MAKE_IDTYPE
(
FOURCC_LIST
,
DMUS_FOURCC_INFO_LIST
):
/* already parsed by dmobj_parsedescriptor */
break
;
case
MAKE_IDTYPE
(
FOURCC_LIST
,
mmioFOURCC
(
's'
,
'd'
,
't'
,
'a'
)):
hr
=
parse_sdta_list
(
This
,
stream
,
&
chunk
,
&
soundfont
);
break
;
case
MAKE_IDTYPE
(
FOURCC_LIST
,
mmioFOURCC
(
'p'
,
'd'
,
't'
,
'a'
)):
hr
=
parse_pdta_list
(
This
,
stream
,
&
chunk
,
&
soundfont
);
break
;
default:
FIXME
(
"Ignoring chunk %s %s
\n
"
,
debugstr_fourcc
(
chunk
.
id
),
debugstr_fourcc
(
chunk
.
type
));
break
;
}
if
(
FAILED
(
hr
))
break
;
}
if
(
SUCCEEDED
(
hr
))
{
TRACE
(
"presets:
\n
"
);
for
(
i
=
0
;
i
<
soundfont
.
preset_count
;
i
++
)
{
struct
sf_preset
*
preset
=
soundfont
.
phdr
+
i
;
TRACE
(
"preset[%u]:
\n
"
,
i
);
TRACE
(
" - name: %s
\n
"
,
debugstr_a
(
preset
->
name
));
TRACE
(
" - preset: %u
\n
"
,
preset
->
preset
);
TRACE
(
" - bank: %u
\n
"
,
preset
->
bank
);
TRACE
(
" - preset_bag_ndx: %u
\n
"
,
preset
->
bag_ndx
);
TRACE
(
" - library: %lu
\n
"
,
preset
->
library
);
TRACE
(
" - genre: %lu
\n
"
,
preset
->
genre
);
TRACE
(
" - morphology: %#lx
\n
"
,
preset
->
morphology
);
for
(
j
=
preset
->
bag_ndx
;
j
<
(
preset
+
1
)
->
bag_ndx
;
j
++
)
{
struct
sf_bag
*
bag
=
soundfont
.
pbag
+
j
;
TRACE
(
" - bag[%u]:
\n
"
,
j
);
TRACE
(
" - gen_ndx: %u
\n
"
,
bag
->
gen_ndx
);
TRACE
(
" - mod_ndx: %u
\n
"
,
bag
->
mod_ndx
);
for
(
k
=
bag
->
gen_ndx
;
k
<
(
bag
+
1
)
->
gen_ndx
;
k
++
)
{
struct
sf_gen
*
gen
=
soundfont
.
pgen
+
k
;
TRACE
(
" - gen[%u]: %s
\n
"
,
k
,
debugstr_sf_gen
(
gen
));
}
for
(
k
=
bag
->
mod_ndx
;
k
<
(
bag
+
1
)
->
mod_ndx
;
k
++
)
{
struct
sf_mod
*
mod
=
soundfont
.
pmod
+
k
;
TRACE
(
" - mod[%u]: %s
\n
"
,
k
,
debugstr_sf_mod
(
mod
));
}
}
}
TRACE
(
"instruments:
\n
"
);
for
(
i
=
0
;
i
<
soundfont
.
instrument_count
;
i
++
)
{
struct
sf_instrument
*
instrument
=
soundfont
.
inst
+
i
;
TRACE
(
"instrument[%u]:
\n
"
,
i
);
TRACE
(
" - name: %s
\n
"
,
debugstr_a
(
instrument
->
name
));
TRACE
(
" - bag_ndx: %u
\n
"
,
instrument
->
bag_ndx
);
for
(
j
=
instrument
->
bag_ndx
;
j
<
(
instrument
+
1
)
->
bag_ndx
;
j
++
)
{
struct
sf_bag
*
bag
=
soundfont
.
ibag
+
j
;
TRACE
(
" - bag[%u]:
\n
"
,
j
);
TRACE
(
" - wGenNdx: %u
\n
"
,
bag
->
gen_ndx
);
TRACE
(
" - wModNdx: %u
\n
"
,
bag
->
mod_ndx
);
for
(
k
=
bag
->
gen_ndx
;
k
<
(
bag
+
1
)
->
gen_ndx
;
k
++
)
{
struct
sf_gen
*
gen
=
soundfont
.
igen
+
k
;
TRACE
(
" - gen[%u]: %s
\n
"
,
k
,
debugstr_sf_gen
(
gen
));
}
for
(
k
=
bag
->
mod_ndx
;
k
<
(
bag
+
1
)
->
mod_ndx
;
k
++
)
{
struct
sf_mod
*
mod
=
soundfont
.
imod
+
k
;
TRACE
(
" - mod[%u]: %s
\n
"
,
k
,
debugstr_sf_mod
(
mod
));
}
}
}
TRACE
(
"samples:
\n
"
);
for
(
i
=
0
;
i
<
soundfont
.
sample_count
;
i
++
)
{
struct
sf_sample
*
sample
=
soundfont
.
shdr
+
i
;
TRACE
(
"sample[%u]:
\n
"
,
i
);
TRACE
(
" - name: %s
\n
"
,
debugstr_a
(
sample
->
name
));
TRACE
(
" - start: %lu
\n
"
,
sample
->
start
);
TRACE
(
" - end: %lu
\n
"
,
sample
->
end
);
TRACE
(
" - start_loop: %lu
\n
"
,
sample
->
start_loop
);
TRACE
(
" - end_loop: %lu
\n
"
,
sample
->
end_loop
);
TRACE
(
" - sample_rate: %lu
\n
"
,
sample
->
sample_rate
);
TRACE
(
" - original_key: %u
\n
"
,
sample
->
original_key
);
TRACE
(
" - correction: %d
\n
"
,
sample
->
correction
);
TRACE
(
" - sample_link: %#x
\n
"
,
sample
->
sample_link
);
TRACE
(
" - sample_type: %#x
\n
"
,
sample
->
sample_type
);
}
}
free
(
soundfont
.
phdr
);
free
(
soundfont
.
pbag
);
free
(
soundfont
.
pmod
);
free
(
soundfont
.
pgen
);
free
(
soundfont
.
inst
);
free
(
soundfont
.
ibag
);
free
(
soundfont
.
imod
);
free
(
soundfont
.
igen
);
free
(
soundfont
.
shdr
);
free
(
soundfont
.
sdta
);
return
hr
;
}
static
HRESULT
WINAPI
collection_object_ParseDescriptor
(
IDirectMusicObject
*
iface
,
IStream
*
stream
,
DMUS_OBJECTDESC
*
desc
)
{
...
...
@@ -366,7 +607,7 @@ static HRESULT WINAPI collection_object_ParseDescriptor(IDirectMusicObject *ifac
if
((
hr
=
stream_get_chunk
(
stream
,
&
riff
))
!=
S_OK
)
return
hr
;
if
(
riff
.
id
!=
FOURCC_RIFF
||
riff
.
type
!=
FOURCC_DLS
)
{
if
(
riff
.
id
!=
FOURCC_RIFF
||
(
riff
.
type
!=
FOURCC_DLS
&&
riff
.
type
!=
mmioFOURCC
(
's'
,
'f'
,
'b'
,
'k'
))
)
{
TRACE
(
"loading failed: unexpected %s
\n
"
,
debugstr_chunk
(
&
riff
));
stream_skip_chunk
(
stream
,
&
riff
);
return
DMUS_E_NOTADLSCOL
;
...
...
@@ -410,6 +651,10 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface, IStream *str
hr
=
parse_dls_chunk
(
This
,
stream
,
&
chunk
);
break
;
case
MAKE_IDTYPE
(
FOURCC_RIFF
,
mmioFOURCC
(
's'
,
'f'
,
'b'
,
'k'
)):
hr
=
parse_sfbk_chunk
(
This
,
stream
,
&
chunk
);
break
;
default:
WARN
(
"Invalid collection chunk %s %s
\n
"
,
debugstr_fourcc
(
chunk
.
id
),
debugstr_fourcc
(
chunk
.
type
));
hr
=
DMUS_E_UNSUPPORTED_STREAM
;
...
...
@@ -439,7 +684,7 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface, IStream *str
}
TRACE
(
" - cues:
\n
"
);
for
(
i
=
0
;
i
<
This
->
pool
->
table
.
cCues
;
i
++
)
for
(
i
=
0
;
This
->
pool
&&
i
<
This
->
pool
->
table
.
cCues
;
i
++
)
TRACE
(
" - index: %u, offset: %lu
\n
"
,
i
,
This
->
pool
->
cues
[
i
].
ulOffset
);
TRACE
(
" - waves:
\n
"
);
...
...
dlls/dmusic/soundfont.h
0 → 100644
View file @
b733a46a
/*
* 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 "stdarg.h"
#include "stddef.h"
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include <pshpack1.h>
/* SoundFont 2.04 data structures, from http://www.synthfont.com/sfspec24.pdf */
struct
sf_range
{
BYTE
low
;
BYTE
high
;
};
union
sf_amount
{
struct
sf_range
range
;
WORD
value
;
};
C_ASSERT
(
sizeof
(
union
sf_amount
)
==
2
);
enum
{
SF_SAMPLE_MONO
=
1
,
SF_SAMPLE_RIGHT
=
2
,
SF_SAMPLE_LEFT
=
4
,
SF_SAMPLE_LINKED
=
8
,
SF_SAMPLE_ROM_MONO
=
0x8001
,
SF_SAMPLE_ROM_RIGHT
=
0x8002
,
SF_SAMPLE_ROM_LEFT
=
0x8004
,
SF_SAMPLE_ROM_LINKED
=
0x8008
,
};
typedef
WORD
sf_sample_type
;
enum
{
SF_GEN_START_ADDRS_OFFSET
=
0
,
SF_GEN_END_ADDRS_OFFSET
=
1
,
SF_GEN_STARTLOOP_ADDRS_OFFSET
=
2
,
SF_GEN_ENDLOOP_ADDRS_OFFSET
=
3
,
SF_GEN_START_ADDRS_COARSE_OFFSET
=
4
,
SF_GEN_MOD_LFO_TO_PITCH
=
5
,
SF_GEN_VIB_LFO_TO_PITCH
=
6
,
SF_GEN_MOD_ENV_TO_PITCH
=
7
,
SF_GEN_INITIAL_FILTER_FC
=
8
,
SF_GEN_INITIAL_FILTER_Q
=
9
,
SF_GEN_MOD_LFO_TO_FILTER_FC
=
10
,
SF_GEN_MOD_ENV_TO_FILTER_FC
=
11
,
SF_GEN_END_ADDRS_COARSE_OFFSET
=
12
,
SF_GEN_MOD_LFO_TO_VOLUME
=
13
,
SF_GEN_CHORUS_EFFECTS_SEND
=
15
,
SF_GEN_REVERB_EFFECTS_SEND
=
16
,
SF_GEN_PAN
=
17
,
SF_GEN_DELAY_MOD_LFO
=
21
,
SF_GEN_FREQ_MOD_LFO
=
22
,
SF_GEN_DELAY_VIB_LFO
=
23
,
SF_GEN_FREQ_VIB_LFO
=
24
,
SF_GEN_DELAY_MOD_ENV
=
25
,
SF_GEN_ATTACK_MOD_ENV
=
26
,
SF_GEN_HOLD_MOD_ENV
=
27
,
SF_GEN_DECAY_MOD_ENV
=
28
,
SF_GEN_SUSTAIN_MOD_ENV
=
29
,
SF_GEN_RELEASE_MOD_ENV
=
30
,
SF_GEN_KEYNUM_TO_MOD_ENV_HOLD
=
31
,
SF_GEN_KEYNUM_TO_MOD_ENV_DECAY
=
32
,
SF_GEN_DELAY_VOL_ENV
=
33
,
SF_GEN_ATTACK_VOL_ENV
=
34
,
SF_GEN_HOLD_VOL_ENV
=
35
,
SF_GEN_DECAY_VOL_ENV
=
36
,
SF_GEN_SUSTAIN_VOL_ENV
=
37
,
SF_GEN_RELEASE_VOL_ENV
=
38
,
SF_GEN_KEYNUM_TO_VOL_ENV_HOLD
=
39
,
SF_GEN_KEYNUM_TO_VOL_ENV_DECAY
=
40
,
SF_GEN_INSTRUMENT
=
41
,
SF_GEN_KEY_RANGE
=
43
,
SF_GEN_VEL_RANGE
=
44
,
SF_GEN_STARTLOOP_ADDRS_COARSE_OFFSET
=
45
,
SF_GEN_KEYNUM
=
46
,
SF_GEN_VELOCITY
=
47
,
SF_GEN_INITIAL_ATTENUATION
=
48
,
SF_GEN_ENDLOOP_ADDRS_COARSE_OFFSET
=
50
,
SF_GEN_COARSE_TUNE
=
51
,
SF_GEN_FINE_TUNE
=
52
,
SF_GEN_SAMPLE_ID
=
53
,
SF_GEN_SAMPLE_MODES
=
54
,
SF_GEN_SCALE_TUNING
=
56
,
SF_GEN_EXCLUSIVE_CLASS
=
57
,
SF_GEN_OVERRIDING_ROOT_KEY
=
58
,
SF_GEN_END_OPER
=
60
,
};
typedef
WORD
sf_generator
;
static
inline
const
char
*
debugstr_sf_generator
(
sf_generator
oper
)
{
switch
(
oper
)
{
case
SF_GEN_START_ADDRS_OFFSET
:
return
"start_addrs_offset"
;
case
SF_GEN_END_ADDRS_OFFSET
:
return
"end_addrs_offset"
;
case
SF_GEN_STARTLOOP_ADDRS_OFFSET
:
return
"startloop_addrs_offset"
;
case
SF_GEN_ENDLOOP_ADDRS_OFFSET
:
return
"endloop_addrs_offset"
;
case
SF_GEN_START_ADDRS_COARSE_OFFSET
:
return
"start_addrs_coarse_offset"
;
case
SF_GEN_MOD_LFO_TO_PITCH
:
return
"mod_lfo_to_pitch"
;
case
SF_GEN_VIB_LFO_TO_PITCH
:
return
"vib_lfo_to_pitch"
;
case
SF_GEN_MOD_ENV_TO_PITCH
:
return
"mod_env_to_pitch"
;
case
SF_GEN_INITIAL_FILTER_FC
:
return
"initial_filter_fc"
;
case
SF_GEN_INITIAL_FILTER_Q
:
return
"initial_filter_q"
;
case
SF_GEN_MOD_LFO_TO_FILTER_FC
:
return
"mod_lfo_to_filter_fc"
;
case
SF_GEN_MOD_ENV_TO_FILTER_FC
:
return
"mod_env_to_filter_fc"
;
case
SF_GEN_END_ADDRS_COARSE_OFFSET
:
return
"end_addrs_coarse_offset"
;
case
SF_GEN_MOD_LFO_TO_VOLUME
:
return
"mod_lfo_to_volume"
;
case
SF_GEN_CHORUS_EFFECTS_SEND
:
return
"chorus_effects_send"
;
case
SF_GEN_REVERB_EFFECTS_SEND
:
return
"reverb_effects_send"
;
case
SF_GEN_PAN
:
return
"pan"
;
case
SF_GEN_DELAY_MOD_LFO
:
return
"delay_mod_lfo"
;
case
SF_GEN_FREQ_MOD_LFO
:
return
"freq_mod_lfo"
;
case
SF_GEN_DELAY_VIB_LFO
:
return
"delay_vib_lfo"
;
case
SF_GEN_FREQ_VIB_LFO
:
return
"freq_vib_lfo"
;
case
SF_GEN_DELAY_MOD_ENV
:
return
"delay_mod_env"
;
case
SF_GEN_ATTACK_MOD_ENV
:
return
"attack_mod_env"
;
case
SF_GEN_HOLD_MOD_ENV
:
return
"hold_mod_env"
;
case
SF_GEN_DECAY_MOD_ENV
:
return
"decay_mod_env"
;
case
SF_GEN_SUSTAIN_MOD_ENV
:
return
"sustain_mod_env"
;
case
SF_GEN_RELEASE_MOD_ENV
:
return
"release_mod_env"
;
case
SF_GEN_KEYNUM_TO_MOD_ENV_HOLD
:
return
"keynum_to_mod_env_hold"
;
case
SF_GEN_KEYNUM_TO_MOD_ENV_DECAY
:
return
"keynum_to_mod_env_decay"
;
case
SF_GEN_DELAY_VOL_ENV
:
return
"delay_vol_env"
;
case
SF_GEN_ATTACK_VOL_ENV
:
return
"attack_vol_env"
;
case
SF_GEN_HOLD_VOL_ENV
:
return
"hold_vol_env"
;
case
SF_GEN_DECAY_VOL_ENV
:
return
"decay_vol_env"
;
case
SF_GEN_SUSTAIN_VOL_ENV
:
return
"sustain_vol_env"
;
case
SF_GEN_RELEASE_VOL_ENV
:
return
"release_vol_env"
;
case
SF_GEN_KEYNUM_TO_VOL_ENV_HOLD
:
return
"keynum_to_vol_env_hold"
;
case
SF_GEN_KEYNUM_TO_VOL_ENV_DECAY
:
return
"keynum_to_vol_env_decay"
;
case
SF_GEN_INSTRUMENT
:
return
"instrument"
;
case
SF_GEN_KEY_RANGE
:
return
"key_range"
;
case
SF_GEN_VEL_RANGE
:
return
"vel_range"
;
case
SF_GEN_STARTLOOP_ADDRS_COARSE_OFFSET
:
return
"startloop_addrs_coarse_offset"
;
case
SF_GEN_KEYNUM
:
return
"keynum"
;
case
SF_GEN_VELOCITY
:
return
"velocity"
;
case
SF_GEN_INITIAL_ATTENUATION
:
return
"initial_attenuation"
;
case
SF_GEN_ENDLOOP_ADDRS_COARSE_OFFSET
:
return
"endloop_addrs_coarse_offset"
;
case
SF_GEN_COARSE_TUNE
:
return
"coarse_tune"
;
case
SF_GEN_FINE_TUNE
:
return
"fine_tune"
;
case
SF_GEN_SAMPLE_ID
:
return
"sample_id"
;
case
SF_GEN_SAMPLE_MODES
:
return
"sample_modes"
;
case
SF_GEN_SCALE_TUNING
:
return
"scale_tuning"
;
case
SF_GEN_EXCLUSIVE_CLASS
:
return
"exclusive_class"
;
case
SF_GEN_OVERRIDING_ROOT_KEY
:
return
"overriding_root_key"
;
case
SF_GEN_END_OPER
:
return
"end_oper"
;
}
return
wine_dbg_sprintf
(
"%u"
,
oper
);
}
enum
{
/* sf_modulator is a set of flags ored together */
SF_MOD_CTRL_GEN_NONE
=
0
,
SF_MOD_CTRL_GEN_VELOCITY
=
0x2
,
SF_MOD_CTRL_GEN_KEY
=
0x3
,
SF_MOD_CTRL_GEN_POLY_PRESSURE
=
0xa
,
SF_MOD_CTRL_GEN_CHAN_PRESSURE
=
0xd
,
SF_MOD_CTRL_GEN_PITCH_WHEEL
=
0xe
,
SF_MOD_CTRL_GEN_PITCH_WHEEL_SENSITIVITY
=
0x10
,
SF_MOD_CTRL_GEN_LINK
=
0x7f
,
SF_MOD_CTRL_GEN
=
0
<<
7
,
SF_MOD_CTRL_MIDI
=
1
<<
7
,
/* with LSB: MIDI CC */
SF_MOD_DIR_INCREASING
=
0
<<
8
,
SF_MOD_DIR_DECREASING
=
1
<<
8
,
SF_MOD_POL_UNIPOLAR
=
0
<<
9
,
SF_MOD_POL_BIPOLAR
=
1
<<
9
,
SF_MOD_SRC_LINEAR
=
0
<<
10
,
SF_MOD_SRC_CONCAVE
=
1
<<
10
,
SF_MOD_SRC_CONVEX
=
2
<<
10
,
SF_MOD_SRC_SWITCH
=
3
<<
10
,
};
typedef
WORD
sf_modulator
;
enum
{
SF_TRAN_LINEAR
=
0
,
SF_TRAN_ABSOLUTE
=
2
,
};
typedef
WORD
sf_transform
;
struct
sf_preset
/* <phdr-rec> */
{
char
name
[
20
];
WORD
preset
;
WORD
bank
;
WORD
bag_ndx
;
DWORD
library
;
DWORD
genre
;
DWORD
morphology
;
};
C_ASSERT
(
sizeof
(
struct
sf_preset
)
==
38
);
struct
sf_bag
/* <pbag-rec> / <ibag-rec> */
{
WORD
gen_ndx
;
WORD
mod_ndx
;
};
C_ASSERT
(
sizeof
(
struct
sf_bag
)
==
4
);
struct
sf_mod
/* <pmod-rec> / <imod-rec> */
{
sf_modulator
src_mod
;
sf_generator
dest_gen
;
SHORT
amount
;
sf_modulator
amount_src_mod
;
sf_transform
transform
;
};
C_ASSERT
(
sizeof
(
struct
sf_mod
)
==
10
);
static
inline
const
char
*
debugstr_sf_mod
(
struct
sf_mod
*
mod
)
{
const
char
*
dest_name
=
debugstr_sf_generator
(
mod
->
dest_gen
);
return
wine_dbg_sprintf
(
"%#x x %#x -> %s: %d (%#x)"
,
mod
->
src_mod
,
mod
->
amount_src_mod
,
dest_name
,
mod
->
amount
,
mod
->
transform
);
}
struct
sf_gen
/* <pgen-rec> / <igen-rec> */
{
sf_generator
oper
;
union
sf_amount
amount
;
};
C_ASSERT
(
sizeof
(
struct
sf_gen
)
==
4
);
static
inline
const
char
*
debugstr_sf_gen
(
struct
sf_gen
*
gen
)
{
const
char
*
name
=
debugstr_sf_generator
(
gen
->
oper
);
switch
(
gen
->
oper
)
{
case
SF_GEN_KEY_RANGE
:
case
SF_GEN_VEL_RANGE
:
return
wine_dbg_sprintf
(
"%s: %u-%u"
,
name
,
gen
->
amount
.
range
.
low
,
gen
->
amount
.
range
.
high
);
default:
return
wine_dbg_sprintf
(
"%s: %u"
,
name
,
gen
->
amount
.
value
);
}
}
struct
sf_instrument
/* <inst-rec> */
{
char
name
[
20
];
WORD
bag_ndx
;
};
C_ASSERT
(
sizeof
(
struct
sf_instrument
)
==
22
);
struct
sf_sample
/* <shdr-rec> */
{
char
name
[
20
];
DWORD
start
;
DWORD
end
;
DWORD
start_loop
;
DWORD
end_loop
;
DWORD
sample_rate
;
BYTE
original_key
;
char
correction
;
WORD
sample_link
;
sf_sample_type
sample_type
;
};
C_ASSERT
(
sizeof
(
struct
sf_sample
)
==
46
);
#include <poppack.h>
struct
soundfont
{
UINT
preset_count
;
struct
sf_preset
*
phdr
;
struct
sf_bag
*
pbag
;
struct
sf_mod
*
pmod
;
struct
sf_gen
*
pgen
;
UINT
instrument_count
;
struct
sf_instrument
*
inst
;
struct
sf_bag
*
ibag
;
struct
sf_mod
*
imod
;
struct
sf_gen
*
igen
;
UINT
sample_count
;
struct
sf_sample
*
shdr
;
BYTE
*
sdta
;
};
dlls/dmusic/tests/dmusic.c
View file @
b733a46a
...
...
@@ -1608,7 +1608,7 @@ static void test_default_gm_collection(void)
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
IDirectMusicLoader_GetObject
(
loader
,
&
desc
,
&
IID_IDirectMusicCollection
,
(
void
**
)
&
collection
);
todo_wine
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
for
(
i
=
0
;
hr
==
S_OK
&&
i
<
ARRAY_SIZE
(
results
);
i
++
)
{
...
...
@@ -1618,7 +1618,7 @@ static void test_default_gm_collection(void)
results
[
i
].
name
,
ARRAY_SIZE
(
results
[
i
].
name
));
}
if
(
hr
==
S_FALSE
)
i
--
;
todo_wine
ok
(
hr
==
S_FALSE
,
"got %#lx
\n
"
,
hr
);
ok
(
hr
==
S_FALSE
,
"got %#lx
\n
"
,
hr
);
todo_wine
ok
(
i
>
0
,
"got %lu
\n
"
,
i
);
todo_wine
ok
(
i
==
ARRAY_SIZE
(
expected
),
"got %lu
\n
"
,
i
);
...
...
@@ -1633,7 +1633,7 @@ static void test_default_gm_collection(void)
winetest_pop_context
();
}
if
(
hr
==
S_FALSE
)
IDirectMusicCollection_Release
(
collection
);
IDirectMusicCollection_Release
(
collection
);
IDirectMusicLoader_Release
(
loader
);
}
...
...
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