Skip to content

Commit 9638bcd

Browse files
committed
Addressing #46
1 parent 8c0b91e commit 9638bcd

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

Sources/CSoundpipeAudioKit/Generators/PhaseLockedVocoderDSP.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
ParameterRamper pitchRatioRamp;
2525

2626
public:
27-
PhaseLockedVocoderDSP() {
27+
PhaseLockedVocoderDSP() : SoundpipeDSPBase(/*inputBusCount*/0) {
2828
parameters[PhaseLockedVocoderParameterPosition] = &positionRamp;
2929
parameters[PhaseLockedVocoderParameterAmplitude] = &amplitudeRamp;
3030
parameters[PhaseLockedVocoderParameterPitchRatio] = &pitchRatioRamp;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#import <XCTest/XCTest.h>
2+
#import <CSoundpipeAudioKit.h>
3+
#import <DSPBase.h>
4+
5+
/// Regression tests for https://github.com/AudioKit/SoundpipeAudioKit/issues/46
6+
///
7+
/// Generators have no audio input bus. If a generator DSP inherits the
8+
/// SoundpipeDSPBase default of `inputBusCount=1`, its bypass path in
9+
/// `DSPBase::processOrBypass` neither zeroes the output (non-empty
10+
/// inputBufferLists skips that branch) nor can it safely copy input
11+
/// (there is no connected input), and with `canProcessInPlace=false`
12+
/// it dereferences an uninitialized buffer and crashes.
13+
///
14+
/// Every generator in this package must therefore be constructed with
15+
/// `inputBusCount=0`.
16+
@interface GeneratorInputBusTests : XCTestCase
17+
@end
18+
19+
@implementation GeneratorInputBusTests
20+
21+
static OSType fourCC(const char *s) {
22+
return (OSType)((uint8_t)s[0] << 24 | (uint8_t)s[1] << 16 | (uint8_t)s[2] << 8 | (uint8_t)s[3]);
23+
}
24+
25+
- (void)assertGeneratorCode:(const char *)code {
26+
DSPRef dsp = akCreateDSP(fourCC(code));
27+
XCTAssertTrue(dsp != NULL, @"Failed to create DSP '%s'", code);
28+
XCTAssertEqual(inputBusCountDSP(dsp), 0UL,
29+
@"Generator '%s' must have inputBusCount=0", code);
30+
deleteDSP(dsp);
31+
}
32+
33+
- (void)testPhaseLockedVocoderIsGenerator {
34+
[self assertGeneratorCode:"minc"];
35+
}
36+
37+
- (void)testAllGeneratorsHaveNoInputBus {
38+
// Codes from AK_REGISTER_DSP in Sources/CSoundpipeAudioKit/Generators/*.mm
39+
const char *codes[] = {
40+
"bron", // BrownianNoise
41+
"csto", // DynamicOscillator
42+
"fosc", // FMOscillator
43+
"mbar", // MetalBar
44+
"morf", // MorphingOscillator
45+
"oscl", // Oscillator
46+
"pdho", // PhaseDistortionOscillator
47+
"minc", // PhaseLockedVocoder
48+
"pink", // PinkNoise
49+
"pluk", // PluckedString
50+
"pwmo", // PWMOscillator
51+
"vocw", // VocalTract
52+
"wnoz", // WhiteNoise
53+
};
54+
for (const char *code : codes) {
55+
[self assertGeneratorCode:code];
56+
}
57+
}
58+
59+
@end

0 commit comments

Comments
 (0)