1 /* 2 * Copyright (C) 2020-2021 Alexandros Theodotou <alex at zrythm dot org> 3 * 4 * This file is part of Zrythm 5 * 6 * Zrythm is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Affero General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * Zrythm is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Affero General Public License for more details. 15 * 16 * You should have received a copy of the GNU Affero General Public License 17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef __UNDO_CHANNEL_SEND_ACTION_H__ 21 #define __UNDO_CHANNEL_SEND_ACTION_H__ 22 23 #include "actions/undoable_action.h" 24 #include "audio/channel_send.h" 25 #include "audio/port_connections_manager.h" 26 27 /** 28 * @addtogroup actions 29 * 30 * @{ 31 */ 32 33 typedef enum ChannelSendActionType 34 { 35 CHANNEL_SEND_ACTION_CONNECT_STEREO, 36 CHANNEL_SEND_ACTION_CONNECT_MIDI, 37 CHANNEL_SEND_ACTION_CONNECT_SIDECHAIN, 38 CHANNEL_SEND_ACTION_CHANGE_AMOUNT, 39 CHANNEL_SEND_ACTION_CHANGE_PORTS, 40 CHANNEL_SEND_ACTION_DISCONNECT, 41 } ChannelSendActionType; 42 43 static const cyaml_strval_t 44 channel_send_action_type_strings[] = 45 { 46 { "Connect stereo", 47 CHANNEL_SEND_ACTION_CONNECT_STEREO }, 48 { "Connect MIDI", 49 CHANNEL_SEND_ACTION_CONNECT_MIDI }, 50 { "Connect sidechain", 51 CHANNEL_SEND_ACTION_CONNECT_SIDECHAIN }, 52 { "Change amount", 53 CHANNEL_SEND_ACTION_CHANGE_AMOUNT }, 54 { "Change ports", 55 CHANNEL_SEND_ACTION_CHANGE_PORTS }, 56 { "Disconnect", 57 CHANNEL_SEND_ACTION_DISCONNECT }, 58 }; 59 60 /** 61 * Action for channel send changes. 62 */ 63 typedef struct ChannelSendAction 64 { 65 UndoableAction parent_instance; 66 67 ChannelSend * send_before; 68 69 float amount; 70 71 /** Target port identifiers. */ 72 PortIdentifier * l_id; 73 PortIdentifier * r_id; 74 PortIdentifier * midi_id; 75 76 /** A clone of the port connections at the 77 * start of the action. */ 78 PortConnectionsManager * connections_mgr_before; 79 80 /** A clone of the port connections after 81 * applying the action. */ 82 PortConnectionsManager * connections_mgr_after; 83 84 /** Action type. */ 85 ChannelSendActionType type; 86 87 } ChannelSendAction; 88 89 static const cyaml_schema_field_t 90 channel_send_action_fields_schema[] = 91 { 92 YAML_FIELD_MAPPING_EMBEDDED ( 93 ChannelSendAction, parent_instance, 94 undoable_action_fields_schema), 95 YAML_FIELD_ENUM ( 96 ChannelSendAction, type, 97 channel_send_action_type_strings), 98 YAML_FIELD_MAPPING_PTR ( 99 ChannelSendAction, send_before, 100 channel_send_fields_schema), 101 YAML_FIELD_MAPPING_PTR_OPTIONAL ( 102 ChannelSendAction, 103 connections_mgr_before, 104 port_connections_manager_fields_schema), 105 YAML_FIELD_MAPPING_PTR_OPTIONAL ( 106 ChannelSendAction, 107 connections_mgr_after, 108 port_connections_manager_fields_schema), 109 110 CYAML_FIELD_END 111 }; 112 113 static const cyaml_schema_value_t 114 channel_send_action_schema = 115 { 116 CYAML_VALUE_MAPPING ( 117 CYAML_FLAG_POINTER, ChannelSendAction, 118 channel_send_action_fields_schema), 119 }; 120 121 void 122 channel_send_action_init_loaded ( 123 ChannelSendAction * self); 124 125 /** 126 * Creates a new action. 127 * 128 * @param port MIDI port, if connecting MIDI. 129 * @param stereo Stereo ports, if connecting audio. 130 * @param port_connections_mgr Port connections 131 * manager at the start of the action, if needed. 132 */ 133 WARN_UNUSED_RESULT 134 UndoableAction * 135 channel_send_action_new ( 136 ChannelSend * send, 137 ChannelSendActionType type, 138 Port * port, 139 StereoPorts * stereo, 140 float amount, 141 const PortConnectionsManager * port_connections_mgr, 142 GError ** error); 143 144 #define channel_send_action_new_disconnect( \ 145 send,error) \ 146 channel_send_action_new ( \ 147 send, CHANNEL_SEND_ACTION_DISCONNECT, NULL, NULL, \ 148 0.f, PORT_CONNECTIONS_MGR, error) 149 150 #define channel_send_action_new_connect_midi( \ 151 send,midi,error) \ 152 channel_send_action_new ( \ 153 send, CHANNEL_SEND_ACTION_CONNECT_MIDI, midi, \ 154 NULL, 0.f, PORT_CONNECTIONS_MGR, error) 155 156 #define channel_send_action_new_connect_audio( \ 157 send,stereo,error) \ 158 channel_send_action_new ( \ 159 send, CHANNEL_SEND_ACTION_CONNECT_STEREO, NULL, \ 160 stereo, 0.f, PORT_CONNECTIONS_MGR, error) 161 162 #define channel_send_action_new_connect_sidechain( \ 163 send,stereo,error) \ 164 channel_send_action_new ( \ 165 send, CHANNEL_SEND_ACTION_CONNECT_SIDECHAIN, \ 166 NULL, stereo, 0.f, PORT_CONNECTIONS_MGR, error) 167 168 #define channel_send_action_new_change_amount( \ 169 send,amt,error) \ 170 channel_send_action_new ( \ 171 send, CHANNEL_SEND_ACTION_CHANGE_AMOUNT, NULL, \ 172 NULL, amt, NULL, error) 173 174 NONNULL 175 ChannelSendAction * 176 channel_send_action_clone ( 177 const ChannelSendAction * src); 178 179 /** 180 * Wrapper to create action and perform it. 181 * 182 * @param port_connections_mgr Port connections 183 * manager at the start of the action, if needed. 184 */ 185 bool 186 channel_send_action_perform ( 187 ChannelSend * send, 188 ChannelSendActionType type, 189 Port * port, 190 StereoPorts * stereo, 191 float amount, 192 const PortConnectionsManager * port_connections_mgr, 193 GError ** error); 194 195 #define channel_send_action_perform_disconnect( \ 196 send,error) \ 197 channel_send_action_perform ( \ 198 send, CHANNEL_SEND_ACTION_DISCONNECT, NULL, NULL, \ 199 0.f, PORT_CONNECTIONS_MGR, error) 200 201 #define channel_send_action_perform_connect_midi( \ 202 send,midi,error) \ 203 channel_send_action_perform ( \ 204 send, CHANNEL_SEND_ACTION_CONNECT_MIDI, midi, \ 205 NULL, 0.f, PORT_CONNECTIONS_MGR, error) 206 207 #define channel_send_action_perform_connect_audio( \ 208 send,stereo,error) \ 209 channel_send_action_perform ( \ 210 send, CHANNEL_SEND_ACTION_CONNECT_STEREO, NULL, \ 211 stereo, 0.f, PORT_CONNECTIONS_MGR, error) 212 213 #define channel_send_action_perform_connect_sidechain( \ 214 send,stereo,error) \ 215 channel_send_action_perform ( \ 216 send, CHANNEL_SEND_ACTION_CONNECT_SIDECHAIN, \ 217 NULL, stereo, 0.f, PORT_CONNECTIONS_MGR, error) 218 219 #define channel_send_action_perform_change_amount( \ 220 send,amt,error) \ 221 channel_send_action_perform ( \ 222 send, CHANNEL_SEND_ACTION_CHANGE_AMOUNT, NULL, \ 223 NULL, amt, NULL, error) 224 225 int 226 channel_send_action_do ( 227 ChannelSendAction * self, 228 GError ** error); 229 230 int 231 channel_send_action_undo ( 232 ChannelSendAction * self, 233 GError ** error); 234 235 char * 236 channel_send_action_stringize ( 237 ChannelSendAction * self); 238 239 void 240 channel_send_action_free ( 241 ChannelSendAction * self); 242 243 /** 244 * @} 245 */ 246 247 #endif 248