Update Fluidsynth to v2.0.4
[ardour.git] / libs / fluidsynth / src / fluid_tuning.c
1 /* FluidSynth - A Software Synthesizer
2  *
3  * Copyright (C) 2003  Peter Hanappe and others.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License
7  * as published by the Free Software Foundation; either version 2.1 of
8  * the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free
17  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  */
20
21
22 #include "fluid_tuning.h"
23 #include "fluid_sys.h"
24
25
26 fluid_tuning_t *new_fluid_tuning(const char *name, int bank, int prog)
27 {
28     fluid_tuning_t *tuning;
29     int i;
30
31     tuning = FLUID_NEW(fluid_tuning_t);
32
33     if(tuning == NULL)
34     {
35         FLUID_LOG(FLUID_PANIC, "Out of memory");
36         return NULL;
37     }
38
39     FLUID_MEMSET(tuning, 0, sizeof(fluid_tuning_t));
40
41     if(fluid_tuning_set_name(tuning, name) != FLUID_OK)
42     {
43         delete_fluid_tuning(tuning);
44         return NULL;
45     }
46
47     tuning->bank = bank;
48     tuning->prog = prog;
49
50     for(i = 0; i < 128; i++)
51     {
52         tuning->pitch[i] = i * 100.0;
53     }
54
55     fluid_atomic_int_set(&tuning->refcount, 1);         /* Start with a refcount of 1 */
56
57     return tuning;
58 }
59
60 /* Duplicate a tuning */
61 fluid_tuning_t *
62 fluid_tuning_duplicate(fluid_tuning_t *tuning)
63 {
64     fluid_tuning_t *new_tuning;
65     int i;
66
67     new_tuning = FLUID_NEW(fluid_tuning_t);
68
69     if(!new_tuning)
70     {
71         FLUID_LOG(FLUID_PANIC, "Out of memory");
72         return NULL;
73     }
74
75     FLUID_MEMSET(new_tuning, 0, sizeof(fluid_tuning_t));
76
77     if(fluid_tuning_set_name(new_tuning, tuning->name) != FLUID_OK)
78     {
79         delete_fluid_tuning(new_tuning);
80         return NULL;
81     }
82
83     new_tuning->bank = tuning->bank;
84     new_tuning->prog = tuning->prog;
85
86     for(i = 0; i < 128; i++)
87     {
88         new_tuning->pitch[i] = tuning->pitch[i];
89     }
90
91     fluid_atomic_int_set(&new_tuning->refcount, 1);     /* Start with a refcount of 1 */
92
93     return new_tuning;
94 }
95
96 void
97 delete_fluid_tuning(fluid_tuning_t *tuning)
98 {
99     fluid_return_if_fail(tuning != NULL);
100
101     FLUID_FREE(tuning->name);
102     FLUID_FREE(tuning);
103 }
104
105 /* Add a reference to a tuning object */
106 void
107 fluid_tuning_ref(fluid_tuning_t *tuning)
108 {
109     fluid_return_if_fail(tuning != NULL);
110
111     fluid_atomic_int_inc(&tuning->refcount);
112 }
113
114 /* Unref a tuning object, when it reaches 0 it is deleted, returns TRUE if deleted */
115 int
116 fluid_tuning_unref(fluid_tuning_t *tuning, int count)
117 {
118     fluid_return_val_if_fail(tuning != NULL, FALSE);
119
120     /* Add and compare are separate, but that is OK, since refcount will only
121      * reach 0 when there are no references and therefore no possibility of
122      * another thread adding a reference in between */
123     fluid_atomic_int_add(&tuning->refcount, -count);
124
125     /* Delete when refcount reaches 0 */
126     if(!fluid_atomic_int_get(&tuning->refcount))
127     {
128         delete_fluid_tuning(tuning);
129         return TRUE;
130     }
131     else
132     {
133         return FALSE;
134     }
135 }
136
137 int fluid_tuning_set_name(fluid_tuning_t *tuning, const char *name)
138 {
139     if(tuning->name != NULL)
140     {
141         FLUID_FREE(tuning->name);
142         tuning->name = NULL;
143     }
144
145     if(name != NULL)
146     {
147         tuning->name = FLUID_STRDUP(name);
148
149         if(tuning->name == NULL)
150         {
151             FLUID_LOG(FLUID_ERR, "Out of memory");
152             return FLUID_FAILED;
153         }
154     }
155
156     return FLUID_OK;
157 }
158
159 char *fluid_tuning_get_name(fluid_tuning_t *tuning)
160 {
161     return tuning->name;
162 }
163
164 void fluid_tuning_set_octave(fluid_tuning_t *tuning, const double *pitch_deriv)
165 {
166     int i;
167
168     for(i = 0; i < 128; i++)
169     {
170         tuning->pitch[i] = i * 100.0 + pitch_deriv[i % 12];
171     }
172 }
173
174 void fluid_tuning_set_all(fluid_tuning_t *tuning, const double *pitch)
175 {
176     int i;
177
178     for(i = 0; i < 128; i++)
179     {
180         tuning->pitch[i] = pitch[i];
181     }
182 }
183
184 void fluid_tuning_set_pitch(fluid_tuning_t *tuning, int key, double pitch)
185 {
186     if((key >= 0) && (key < 128))
187     {
188         tuning->pitch[key] = pitch;
189     }
190 }