Skip to content

Instantly share code, notes, and snippets.

@mdales
Created May 29, 2018 14:58
Show Gist options
  • Save mdales/e05a62fc62dd2de81a59452b6391916a to your computer and use it in GitHub Desktop.
Save mdales/e05a62fc62dd2de81a59452b6391916a to your computer and use it in GitHub Desktop.
import Foundation
struct SoundSample {}
protocol Effect: Codable {
var type: EffectType { get }
// Properties that we want
var name: String { get set }
var active: Bool { get set }
func doEffect(_ s: SoundSample) -> Void
}
struct ReverbEffect: Effect {
let type = EffectType.reverb
var name = "Reverb"
var active = true
var delay = 3.2
var feedback = 40
func doEffect(_ s: SoundSample) -> Void { /* some custom reverb code here */ }
}
struct DistortionEffect: Effect {
let type = EffectType.distortion
var name = "Distorion"
var active = true
var gain = 1.5
var tone = 6
func doEffect(_ s: SoundSample) -> Void { /* some custom distortion code here */ }
}
enum EffectType : String, Codable {
case reverb, distortion
var metatype: Effect.Type {
switch self {
case .reverb:
return ReverbEffect.self
case .distortion:
return DistortionEffect.self
}
}
}
struct EffectWrapper {
var effect: Effect
}
extension EffectWrapper: Codable {
private enum CodingKeys: CodingKey {
case type, effect
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let type = try container.decode(EffectType.self, forKey: .type)
self.effect = try type.metatype.init(from: container.superDecoder(forKey: .effect))
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(effect.type, forKey: .type)
try effect.encode(to: container.superEncoder(forKey: .effect))
}
}
let effectsChain: [Effect] = [ReverbEffect(), DistortionEffect()]
// normal operations will be things like this:
let s = SoundSample()
for effect in effectsChain {
effect.doEffect(s)
}
// Then play sample
// Save our chain as JSON for saving and restoring
do {
let wrappedChain: [EffectWrapper] = effectsChain.map{EffectWrapper(effect:$0)}
let jsonData = try JSONEncoder().encode(wrappedChain)
let jsonString = String(data: jsonData, encoding: .utf8)
if let json = jsonString {
print(json)
}
// now restore
let newChain = try? JSONDecoder().decode([EffectWrapper].self, from:jsonData)
if let new = newChain {
print("We restored the chain: %@", new)
}
} catch {
// blah
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment