1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-29 12:50:28 +00:00

Adds test data for FM wave generation.

This commit is contained in:
Thomas Harte 2020-04-20 19:33:03 -04:00
parent f19fd7c166
commit 3852e119aa
3 changed files with 122 additions and 27 deletions

View File

@ -152,6 +152,7 @@
4B1D08061E0F7A1100763741 /* TimeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B1D08051E0F7A1100763741 /* TimeTests.mm */; }; 4B1D08061E0F7A1100763741 /* TimeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B1D08051E0F7A1100763741 /* TimeTests.mm */; };
4B1E85811D176468001EF87D /* 6532Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E85801D176468001EF87D /* 6532Tests.swift */; }; 4B1E85811D176468001EF87D /* 6532Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E85801D176468001EF87D /* 6532Tests.swift */; };
4B1EDB451E39A0AC009D6819 /* chip.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B1EDB431E39A0AC009D6819 /* chip.png */; }; 4B1EDB451E39A0AC009D6819 /* chip.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B1EDB431E39A0AC009D6819 /* chip.png */; };
4B2530F4244E6774007980BF /* fm.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B2530F3244E6773007980BF /* fm.json */; };
4B2A332D1DB86821002876E3 /* OricOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2A332B1DB86821002876E3 /* OricOptions.xib */; }; 4B2A332D1DB86821002876E3 /* OricOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2A332B1DB86821002876E3 /* OricOptions.xib */; };
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; }; 4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; };
4B2B3A4B1F9B8FA70062DABF /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; }; 4B2B3A4B1F9B8FA70062DABF /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; };
@ -1007,6 +1008,7 @@
4B1E85801D176468001EF87D /* 6532Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6532Tests.swift; sourceTree = "<group>"; }; 4B1E85801D176468001EF87D /* 6532Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6532Tests.swift; sourceTree = "<group>"; };
4B1EDB431E39A0AC009D6819 /* chip.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chip.png; sourceTree = "<group>"; }; 4B1EDB431E39A0AC009D6819 /* chip.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chip.png; sourceTree = "<group>"; };
4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = "<group>"; }; 4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = "<group>"; };
4B2530F3244E6773007980BF /* fm.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = fm.json; sourceTree = "<group>"; };
4B2A332C1DB86821002876E3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/OricOptions.xib"; sourceTree = SOURCE_ROOT; }; 4B2A332C1DB86821002876E3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/OricOptions.xib"; sourceTree = SOURCE_ROOT; };
4B2A53901D117D36003C6002 /* CSAudioQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSAudioQueue.h; sourceTree = "<group>"; }; 4B2A53901D117D36003C6002 /* CSAudioQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSAudioQueue.h; sourceTree = "<group>"; };
4B2A53911D117D36003C6002 /* CSAudioQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSAudioQueue.m; sourceTree = "<group>"; }; 4B2A53911D117D36003C6002 /* CSAudioQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSAudioQueue.m; sourceTree = "<group>"; };
@ -1968,9 +1970,7 @@
4B1414631B588A1100E04248 /* Test Binaries */ = { 4B1414631B588A1100E04248 /* Test Binaries */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B670A822401CB8400D4E002 /* Patrik Rak Z80 Tests */,
4B680CE323A555CA00451D43 /* 68000 Comparative Tests */, 4B680CE323A555CA00451D43 /* 68000 Comparative Tests */,
4B85322B227793CA00F26553 /* TOS Startup */,
4B9252CD1E74D28200B76AF1 /* Atari ROMs */, 4B9252CD1E74D28200B76AF1 /* Atari ROMs */,
4B44EBF81DC9898E00A7820C /* BCDTEST_beeb */, 4B44EBF81DC9898E00A7820C /* BCDTEST_beeb */,
4B98A1CD1FFADEC400ADF63B /* MSX ROMs */, 4B98A1CD1FFADEC400ADF63B /* MSX ROMs */,
@ -1978,8 +1978,11 @@
4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */, 4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */,
4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */, 4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */,
4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */, 4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */,
4B2530F2244E6773007980BF /* FM Synthesis */,
4BBF49B41ED2881600AB3669 /* FUSE */, 4BBF49B41ED2881600AB3669 /* FUSE */,
4B670A822401CB8400D4E002 /* Patrik Rak Z80 Tests */,
4B9F11C72272375400701480 /* QL Startup */, 4B9F11C72272375400701480 /* QL Startup */,
4B85322B227793CA00F26553 /* TOS Startup */,
4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */, 4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */,
4BE9A6B21EDE294200CBCB47 /* Zexall */, 4BE9A6B21EDE294200CBCB47 /* Zexall */,
); );
@ -2051,6 +2054,14 @@
path = ../../SignalProcessing; path = ../../SignalProcessing;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
4B2530F2244E6773007980BF /* FM Synthesis */ = {
isa = PBXGroup;
children = (
4B2530F3244E6773007980BF /* fm.json */,
);
path = "FM Synthesis";
sourceTree = "<group>";
};
4B2A538F1D117D36003C6002 /* Audio */ = { 4B2A538F1D117D36003C6002 /* Audio */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -4293,6 +4304,7 @@
4BB299611B587D8400A49093 /* insax in Resources */, 4BB299611B587D8400A49093 /* insax in Resources */,
4BB299351B587D8400A49093 /* cmpix in Resources */, 4BB299351B587D8400A49093 /* cmpix in Resources */,
4B9F11C92272375400701480 /* qltrace.txt.gz in Resources */, 4B9F11C92272375400701480 /* qltrace.txt.gz in Resources */,
4B2530F4244E6774007980BF /* fm.json in Resources */,
4BB299041B587D8400A49093 /* aneb in Resources */, 4BB299041B587D8400A49093 /* aneb in Resources */,
4BB299BB1B587D8400A49093 /* rraa in Resources */, 4BB299BB1B587D8400A49093 /* rraa in Resources */,
4BB299091B587D8400A49093 /* aslz in Resources */, 4BB299091B587D8400A49093 /* aslz in Resources */,

File diff suppressed because one or more lines are too long

View File

@ -29,27 +29,7 @@
} }
} }
- (void)testADSR { - (void)compareFMTo:(NSArray *)knownGood atAttenuation:(int)attenuation {
Yamaha::OPL::Operator test_operator;
Yamaha::OPL::OperatorState test_state;
test_operator.set_attack_decay(0x88);
test_operator.set_sustain_release(0x88);
// While key is off, output level should remain at 0.
for(int c = 0; c < 1024; ++c) {
test_operator.update(test_state, false, 0, 0, 0);
XCTAssertGreaterThanOrEqual(test_state.level(), 0);
}
// Set key on...
for(int c = 0; c < 4096; ++c) {
test_operator.update(test_state, true, 0, 0, 0);
NSLog(@"%d", test_state.level());
}
}
- (void)testFM {
Yamaha::OPL::Operator modulator, carrier; Yamaha::OPL::Operator modulator, carrier;
Yamaha::OPL::Channel channel; Yamaha::OPL::Channel channel;
@ -58,7 +38,7 @@
carrier.set_am_vibrato_hold_sustain_ksr_multiple(0x20); carrier.set_am_vibrato_hold_sustain_ksr_multiple(0x20);
// Set: KL = 0, TL = 0 // Set: KL = 0, TL = 0
modulator.set_scaling_output(0x3f); modulator.set_scaling_output(attenuation);
carrier.set_scaling_output(0); carrier.set_scaling_output(0);
// Set: waveform = 0. // Set: waveform = 0.
@ -80,11 +60,48 @@
channel.set_frequency_low(0x40); channel.set_frequency_low(0x40);
channel.set_9bit_frequency_octave_key_on(0x10); channel.set_9bit_frequency_octave_key_on(0x10);
// Grab a bunch of samples. // Check one complete cycle of samples.
NSEnumerator *goodValues = [knownGood objectEnumerator];
for(int c = 0; c < 16384; ++c) { for(int c = 0; c < 16384; ++c) {
printf("%d\n", channel.update(&modulator, &carrier)); const int generated = channel.update(&modulator, &carrier);
const int known = [[goodValues nextObject] intValue];
XCTAssertLessThanOrEqual(abs(generated - known), 10, "FM synthesis varies by more than 10 at sample %d of attenuation %d", c, attenuation);
}
}
- (void)testFM {
// The following have been verified by sight against
// the images at https://www.smspower.org/Development/RE10
// as "close enough". Sadly the raw data isn't given, so
// that's the best as I can do. Fingers crossed!
NSURL *const url = [[NSBundle bundleForClass:[self class]] URLForResource:@"fm" withExtension:@"json"];
NSArray *const parent = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL:url] options:0 error:nil];
for(int c = 0; c < 64; ++c) {
[self compareFMTo:parent[c] atAttenuation:c];
}
}
- (void)testADSR {
Yamaha::OPL::Operator test_operator;
Yamaha::OPL::OperatorState test_state;
test_operator.set_attack_decay(0x88);
test_operator.set_sustain_release(0x88);
// While key is off, output level should remain at 0.
for(int c = 0; c < 1024; ++c) {
test_operator.update(test_state, false, 0, 0, 0);
XCTAssertGreaterThanOrEqual(test_state.level(), 0);
}
// Set key on...
for(int c = 0; c < 4096; ++c) {
test_operator.update(test_state, true, 0, 0, 0);
NSLog(@"%d", test_state.level());
} }
printf("\n");
} }
@end @end