2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2011 Krzysztof Foltman
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "sfzparser.h"
22 #define DUMP_LAYER_ATTRIBS 0
26 struct sampler_module
*m
;
28 struct sampler_program
*program
;
29 struct sampler_layer
*group
;
30 struct sampler_layer
*region
;
35 static void load_sfz_end_region(struct sfz_parser_client
*client
)
37 struct sfz_load_state
*ls
= client
->user_data
;
38 // printf("-- copy current region to the list of layers\n");
39 struct sampler_layer
*l
= ls
->region
;
40 sampler_layer_data_finalize(&l
->data
, l
->parent_group
? &l
->parent_group
->data
: NULL
, ls
->program
);
41 sampler_layer_reset_switches(l
, ls
->m
);
42 sampler_layer_update(l
);
43 sampler_program_add_layer(ls
->program
, ls
->region
);
48 static void end_token(struct sfz_parser_client
*client
)
50 struct sfz_load_state
*ls
= client
->user_data
;
51 #if DUMP_LAYER_ATTRIBS
54 fprintf(stdout
, "<group>");
55 sampler_layer_dump(&ls
->group
, stdout
);
59 fprintf(stdout
, "<region>");
60 sampler_layer_dump(&ls
->region
, stdout
);
64 load_sfz_end_region(client
);
65 ls
->is_control
= FALSE
;
68 static gboolean
load_sfz_group(struct sfz_parser_client
*client
)
70 struct sfz_load_state
*ls
= client
->user_data
;
71 // printf("-- start group\n");
72 ls
->group
= sampler_layer_new(ls
->m
, ls
->program
, NULL
);
73 sampler_program_add_group(ls
->program
, ls
->group
);
77 static gboolean
load_sfz_region(struct sfz_parser_client
*client
)
79 struct sfz_load_state
*ls
= client
->user_data
;
81 ls
->region
= sampler_layer_new(ls
->m
, ls
->program
, ls
->group
);
82 // g_warning("-- start region");
86 static gboolean
load_sfz_key_value(struct sfz_parser_client
*client
, const char *key
, const char *value
)
88 struct sfz_load_state
*ls
= client
->user_data
;
92 if (!strncmp(key
, "set_cc", 6))
94 int ctrl
= atoi(key
+ 6);
95 int val
= atoi(value
);
96 if (ctrl
>= 0 && ctrl
<= 119 && val
>=0 && val
<= 127)
97 sampler_program_add_controller_init(ls
->program
, ctrl
, val
);
99 g_warning("Invalid CC initialisation: %s=%s", key
, value
);
102 g_warning("Unrecognized SFZ key in control section: %s", key
);
106 struct sampler_layer
*l
= ls
->region
? ls
->region
: ls
->group
;
107 if (!ls
->region
&& !ls
->group
)
109 g_warning("Cannot use parameter '%s' outside of region or group", key
);
113 if (!sampler_layer_apply_param(l
, key
, value
, ls
->error
))
119 static gboolean
handle_token(struct sfz_parser_client
*client
, const char *token
, GError
**error
)
121 struct sfz_load_state
*ls
= client
->user_data
;
124 if (!strcmp(token
, "region"))
125 return load_sfz_region(client
);
127 if (!strcmp(token
, "group"))
128 return load_sfz_group(client
);
130 if (!strcmp(token
, "control"))
132 ls
->is_control
= TRUE
;
136 g_set_error(error
, CBOX_SFZPARSER_ERROR
, CBOX_SFZ_PARSER_ERROR_INVALID_HEADER
, "Unexpected header <%s>", token
);
140 gboolean
sampler_module_load_program_sfz(struct sampler_module
*m
, struct sampler_program
*prg
, const char *sfz
, int is_from_string
, GError
**error
)
142 struct sfz_load_state ls
= { .group
= prg
->default_group
, .m
= m
, .filename
= sfz
, .region
= NULL
, .error
= error
, .program
= prg
, .is_control
= FALSE
};
143 struct sfz_parser_client c
= { .user_data
= &ls
, .token
= handle_token
, .key_value
= load_sfz_key_value
};
144 g_clear_error(error
);
148 status
= load_sfz_from_string(sfz
, strlen(sfz
), &c
, error
);
150 status
= load_sfz(sfz
, prg
->tarfile
, &c
, error
);
154 CBOX_DELETE(ls
.region
);
160 prg
->all_layers
= g_slist_reverse(prg
->all_layers
);
161 sampler_program_update_layers(prg
);