diff --git a/src/mixer.c b/src/mixer.c index 01cc17f419..af77359755 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -613,7 +613,7 @@ void fix_mixer_dependencies(unsigned mixer_count) mixers[i].src = 0; } memset(placed, 0, sizeof(placed)); - while(mixer_count || last_count != mixer_count) { + while(mixer_count && last_count != mixer_count) { last_count = mixer_count; for (i = 0; i < NUM_SOURCES; i++) { if (placed[i]) @@ -626,7 +626,7 @@ void fix_mixer_dependencies(unsigned mixer_count) unsigned j; // determine if all dependencies have been placed for (j = 0; j < NUM_SOURCES; j++) { - if (dependencies[i] && ! placed[i]) { + if (dependencies[j] && ! placed[j]) { ok = 0; break; } @@ -639,13 +639,17 @@ void fix_mixer_dependencies(unsigned mixer_count) } } } - //mixer_count s gauranteed to be 0 when we get here - //if (mixer_count) { - // printf("Could not place all mixers!\n"); - // return; - //} - for (i = 0; i < NUM_MIXERS; i++) - Model.mixers[i] = mixers[i]; + if (mixer_count) { + // We found a mixer loop....add missing mixers to the end of the order + printf("Mix loop detected. The following mixers may have a circular dependency!\n"); + for (unsigned source = 0; source < NUM_SOURCES; source++) { + if (placed[source]) + continue; + printf(" Mixer source: %d\n", source); + pos += MIXER_GetMixers(source, &mixers[pos], NUM_MIXERS); + } + } + memcpy(Model.mixers, mixers, sizeof(mixers)); } int MIXER_SetMixers(struct Mixer *mixers, int count) diff --git a/src/tests/test_mixer.c b/src/tests/test_mixer.c index cab8de81ef..bde1ef7704 100644 --- a/src/tests/test_mixer.c +++ b/src/tests/test_mixer.c @@ -686,6 +686,61 @@ void TestSetMixers(CuTest *t) } } +#define TO_SOURCE(x) ((x) < 0 ? (NUM_SOURCES + 1 - (x)) : (x)) +#define FROM_SOURCE(x) ((x) > NUM_SOURCES ? -((x)-NUM_SOURCES-1) : (x)) +void TestSetMixerDepends(CuTest *t) +{ + int sources[] = {-6, 1, -2, 1, -1, 1}; + int switches[] = { 0, 0, 0, -5, 0, 0}; + int dests[] = { 4, 1, 6, 6, 2, 5}; + memset(&Model, 0, sizeof(Model)); + for (unsigned i = 0; i < sizeof(Model.templates)/sizeof(Model.templates[0]); i++) { + Model.templates[i] = MIXERTEMPLATE_SIMPLE; + } + for (unsigned i = 0; i < sizeof(sources)/sizeof(sources[0]); i++) { + Model.mixers[i].src = TO_SOURCE(sources[i]); + Model.mixers[i].sw = TO_SOURCE(switches[i]); + Model.mixers[i].dest = dests[i]; + Model.mixers[i].scalar = i; + Model.mixers[i].curve.type = CURVE_FIXED; + } + MIXER_SetMixers(NULL, 0); + int expected[] = {1, 4, 5, 2, 3, 0}; + for (unsigned i = 0; i < sizeof(sources)/sizeof(sources[0]); i++) { + //printf("%d: orig:%d src:%d sw:%d dest:%d\n", + // i, Model.mixers[i].scalar, FROM_SOURCE(Model.mixers[i].src), + // FROM_SOURCE(Model.mixers[i].sw), Model.mixers[i].dest); + CuAssertIntEquals(t, expected[i], Model.mixers[i].scalar); + } +} + +void TestSetMixerLoop(CuTest *t) +{ + //negaitve values mean to use a dest as source + int sources[] = {-6, 1, -2, 1, -1, 1}; + int switches[] = { 0, 0, 0, -5, 0, 0}; + int dests[] = { 1, 4, 6, 6, 2, 5}; + memset(&Model, 0, sizeof(Model)); + for (unsigned i = 0; i < sizeof(Model.templates)/sizeof(Model.templates[0]); i++) { + Model.templates[i] = MIXERTEMPLATE_SIMPLE; + } + for (unsigned i = 0; i < sizeof(sources)/sizeof(sources[0]); i++) { + Model.mixers[i].src = TO_SOURCE(sources[i]); + Model.mixers[i].sw = TO_SOURCE(switches[i]); + Model.mixers[i].dest = dests[i]; + Model.mixers[i].scalar = i; + Model.mixers[i].curve.type = CURVE_FIXED; + } + MIXER_SetMixers(NULL, 0); + int expected[] = {1, 5, 0, 4, 2, 3}; + for (unsigned i = 0; i < sizeof(sources)/sizeof(sources[0]); i++) { + //printf("%d: orig:%d src:%d sw:%d dest:%d\n", + // i, Model.mixers[i].scalar, FROM_SOURCE(Model.mixers[i].src), + // FROM_SOURCE(Model.mixers[i].sw), Model.mixers[i].dest); + CuAssertIntEquals(t, expected[i], Model.mixers[i].scalar); + } +} + void TestGetLimit(CuTest *t) { struct Limit limit = {0};