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/>.
26 static void clear_meter(struct cbox_meter
*m
)
28 for (int i
= 0; i
< 2; i
++)
32 m
->last_peak
[i
] = 0.f
;
37 gboolean
cbox_meter_attach(struct cbox_recorder
*handler
, struct cbox_recording_source
*src
, GError
**error
)
39 struct cbox_meter
*m
= handler
->user_data
;
40 m
->channels
= src
->channels
;
45 void cbox_meter_record_block(struct cbox_recorder
*handler
, const float **buffers
, uint32_t numsamples
)
47 struct cbox_meter
*m
= handler
->user_data
;
48 for (int c
= 0; c
< m
->channels
; c
++)
50 float peak
= m
->peak
[c
];
51 float volume
= m
->volume
[c
];
52 for (int i
= 0; i
< numsamples
; i
++)
54 float s
= buffers
[c
][i
];
57 volume
+= (s
* s
- volume
) * 0.01; // XXXKF this is too simplistic, needs sample rate and proper time constant
60 m
->volume
[c
] = sanef(volume
);
62 m
->smpcounter
+= numsamples
;
63 if (m
->smpcounter
> m
->srate
)
65 for (int c
= 0; c
< m
->channels
; c
++)
67 m
->last_peak
[c
] = m
->peak
[c
];
74 gboolean
cbox_meter_detach(struct cbox_recorder
*handler
, GError
**error
)
76 struct cbox_meter
*m
= handler
->user_data
;
82 void cbox_meter_destroy(struct cbox_recorder
*handler
)
84 struct cbox_meter
*m
= handler
->user_data
;
88 static gboolean
cbox_meter_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
90 struct cbox_meter
*m
= ct
->user_data
;
91 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
93 return CBOX_OBJECT_DEFAULT_STATUS(&m
->recorder
, fb
, error
);
95 if (!strcmp(cmd
->command
, "/get_peak") && !strcmp(cmd
->arg_types
, ""))
97 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
101 for (int c
= 0; c
< 2; c
++)
103 float v
= m
->peak
[c
], w
= m
->last_peak
[c
];
109 return cbox_execute_on(fb
, NULL
, "/peak", "ff", error
, peak
[0], peak
[1]);
112 if (!strcmp(cmd
->command
, "/get_rms") && !strcmp(cmd
->arg_types
, ""))
114 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
117 return cbox_execute_on(fb
, NULL
, "/rms", "ff", error
, sqrt(m
->volume
[0]), sqrt(m
->volume
[1]));
120 return cbox_object_default_process_cmd(ct
, fb
, cmd
, error
);
123 struct cbox_meter
*cbox_meter_new(struct cbox_document
*document
, int srate
)
125 struct cbox_meter
*m
= malloc(sizeof(struct cbox_meter
));
126 CBOX_OBJECT_HEADER_INIT(&m
->recorder
, cbox_recorder
, document
);
127 m
->recorder
.user_data
= m
;
128 cbox_command_target_init(&m
->recorder
.cmd_target
, cbox_meter_process_cmd
, m
);
129 m
->recorder
.attach
= cbox_meter_attach
;
130 m
->recorder
.detach
= cbox_meter_detach
;
131 m
->recorder
.record_block
= cbox_meter_record_block
;
132 m
->recorder
.destroy
= cbox_meter_destroy
;
135 CBOX_OBJECT_REGISTER(&m
->recorder
);