{-# LANGUAGE OverloadedStrings #-} module Sound.Tidal.StepwiseTest where import Sound.Tidal.Control (chop, hurry, striate) import Sound.Tidal.Core () import Sound.Tidal.Params (sound) import Sound.Tidal.ParseBP () import Sound.Tidal.Pattern ( ArcF (Arc), Pattern (tactus), fast, rev, ) import Sound.Tidal.Stepwise (expand, stepcat, stepdrop, steptake) import Sound.Tidal.UI (inv, iter, linger, segment) import Test.Microspec ( MTestable (describe), Microspec, it, shouldBe, ) import TestUtils (compareP, firstCycleValues) import Prelude hiding ((*>), (<*)) run :: Microspec () run = describe "Sound.Tidal.Stepwise" $ do describe "stepcat" $ do it "can stepwise cat" $ do compareP (Arc 0 8) (stepcat ["a b c", "d e" :: Pattern String]) "a b c d e" describe "expand" $ do it "can pattern expands" $ do compareP (Arc 0 8) (expand "2 1" ("a b c" :: Pattern Char)) "a@2 b@2 c@2 a b c" describe "steptake" $ do it "can pattern takes" $ do compareP (Arc 0 8) (steptake "1 2 3 4" ("a b c d" :: Pattern Char)) "a a b a b c a b c d" it "can pattern reverse takes" $ do compareP (Arc 0 8) (steptake "-1 -2 -3 -4" ("a b c d" :: Pattern Char)) "d c d b c d a b c d" describe "stepdrop" $ do it "can pattern drops" $ do compareP (Arc 0 8) (stepdrop "0 1 2 3" ("a b c d" :: Pattern Char)) "a b c d a b c a b a" it "can pattern reverse drops" $ do compareP (Arc 0 8) (stepdrop "0 -1 -2 -3" ("a b c d" :: Pattern Char)) "a b c d b c d c d d" describe "tactus" $ do it "is correctly preserved/calculated through transformations" $ do it "linger" $ (firstCycleValues <$> tactus (linger 4 "a b c" :: Pattern Char)) `shouldBe` Just [3] it "iter" $ (firstCycleValues <$> tactus (iter 4 "a b c" :: Pattern Char)) `shouldBe` Just [3] it "fast" $ (firstCycleValues <$> tactus (fast 4 "a b c" :: Pattern Char)) `shouldBe` Just [3] it "hurry" $ (firstCycleValues <$> tactus (hurry 4 $ sound "a b c")) `shouldBe` Just [3] it "rev" $ (firstCycleValues <$> tactus (rev "a b c" :: Pattern Char)) `shouldBe` Just [3] it "segment" $ (firstCycleValues <$> tactus (segment 10 "a" :: Pattern Char)) `shouldBe` Just [10] it "invert" $ (firstCycleValues <$> tactus (inv "1 0 1" :: Pattern Bool)) `shouldBe` Just [3] it "chop" $ (firstCycleValues <$> tactus (chop 3 $ sound "a b")) `shouldBe` Just [6] it "chop" $ (firstCycleValues <$> tactus (striate 3 $ sound "a b")) `shouldBe` Just [6] -- expect(sequence({ s: 'bev' }, { s: 'amenbreak' }).chop(4).tactus).toStrictEqual(Fraction(8)); -- expect(sequence({ s: 'bev' }, { s: 'amenbreak' }).striate(4).tactus).toStrictEqual(Fraction(8)); -- expect(sequence({ s: 'bev' }, { s: 'amenbreak' }).slice(4, sequence(0, 1, 2, 3)).tactus).toStrictEqual( -- Fraction(4), -- ); -- expect(sequence({ s: 'bev' }, { s: 'amenbreak' }).splice(4, sequence(0, 1, 2, 3)).tactus).toStrictEqual( -- Fraction(4), -- ); -- expect(sequence({ n: 0 }, { n: 1 }, { n: 2 }).chop(4).tactus).toStrictEqual(Fraction(12)); -- expect( -- pure((x) => x + 1) -- .setTactus(3) -- .appBoth(pure(1).setTactus(2)).tactus, -- ).toStrictEqual(Fraction(6)); -- expect( -- pure((x) => x + 1) -- .setTactus(undefined) -- .appBoth(pure(1).setTactus(2)).tactus, -- ).toStrictEqual(Fraction(2)); -- expect( -- pure((x) => x + 1) -- .setTactus(3) -- .appBoth(pure(1).setTactus(undefined)).tactus, -- ).toStrictEqual(Fraction(3)); -- expect(stack(fastcat(0, 1, 2), fastcat(3, 4)).tactus).toStrictEqual(Fraction(6)); -- expect(stack(fastcat(0, 1, 2), fastcat(3, 4).setTactus(undefined)).tactus).toStrictEqual(Fraction(3)); -- expect(stackLeft(fastcat(0, 1, 2, 3), fastcat(3, 4)).tactus).toStrictEqual(Fraction(4)); -- expect(stackRight(fastcat(0, 1, 2), fastcat(3, 4)).tactus).toStrictEqual(Fraction(3)); -- // maybe this should double when they are either all even or all odd -- expect(stackCentre(fastcat(0, 1, 2), fastcat(3, 4)).tactus).toStrictEqual(Fraction(3)); -- expect(fastcat(0, 1).ply(3).tactus).toStrictEqual(Fraction(6)); -- expect(fastcat(0, 1).setTactus(undefined).ply(3).tactus).toStrictEqual(undefined); -- expect(fastcat(0, 1).fast(3).tactus).toStrictEqual(Fraction(2)); -- expect(fastcat(0, 1).setTactus(undefined).fast(3).tactus).toStrictEqual(undefined); -- }); -- }); -- describe('stepcat', () => { -- it('can cat', () => { -- expect(sameFirst(stepcat(fastcat(0, 1, 2, 3), fastcat(4, 5)), fastcat(0, 1, 2, 3, 4, 5))); -- expect(sameFirst(stepcat(pure(1), pure(2), pure(3)), fastcat(1, 2, 3))); -- }); -- it('calculates undefined tactuses as the average', () => { -- expect(sameFirst(stepcat(pure(1), pure(2), pure(3).setTactus(undefined)), fastcat(1, 2, 3))); -- }); -- }); -- describe('taper', () => { -- it('can taper', () => { -- expect(sameFirst(sequence(0, 1, 2, 3, 4).taper(1, 5), sequence(0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 0, 1, 0))); -- }); -- it('can taper backwards', () => { -- expect(sameFirst(sequence(0, 1, 2, 3, 4).taper(-1, 5), sequence(0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4))); -- }); -- }); -- describe('increase and decrease', () => { -- it('can increase from the left', () => { -- expect(sameFirst(sequence(0, 1, 2, 3, 4).increase(2), sequence(0, 1))); -- }); -- it('can decrease to the left', () => { -- expect(sameFirst(sequence(0, 1, 2, 3, 4).decrease(2), sequence(0, 1, 2))); -- }); -- it('can increase from the right', () => { -- expect(sameFirst(sequence(0, 1, 2, 3, 4).increase(-2), sequence(3, 4))); -- }); -- it('can decrease to the right', () => { -- expect(sameFirst(sequence(0, 1, 2, 3, 4).decrease(-2), sequence(2, 3, 4))); -- }); -- it('can decrease nothing', () => { -- expect(sameFirst(pure('a').decrease(0), pure('a'))); -- }); -- it('can decrease nothing, repeatedly', () => { -- expect(sameFirst(pure('a').decrease(0, 0), fastcat('a', 'a'))); -- for (var i = 0; i < 100; ++i) { -- expect(sameFirst(pure('a').decrease(...Array(i).fill(0)), fastcat(...Array(i).fill('a')))); -- } -- }); -- }); -- describe('expand', () => { -- it('can expand four things in half', () => { -- expect( -- sameFirst(sequence(0, 1, 2, 3).expand(1, 0.5), stepcat(sequence(0, 1, 2, 3), sequence(0, 1, 2, 3).expand(0.5))), -- ); -- }); -- it('can expand five things in half', () => { -- expect( -- sameFirst( -- sequence(0, 1, 2, 3, 4).expand(1, 0.5), -- stepcat(sequence(0, 1, 2, 3, 4), sequence(0, 1, 2, 3, 4).expand(0.5)), -- ), -- ); -- }); -- }); -- describe('stepJoin', () => { -- it('can join a pattern with a tactus of 2', () => { -- expect( -- sameFirst( -- sequence(pure(pure('a')), pure(pure('b').setTactus(2))).stepJoin(), -- stepcat(pure('a'), pure('b').setTactus(2)), -- ), -- ); -- }); -- it('can join a pattern with a tactus of 0.5', () => { -- expect( -- sameFirst( -- sequence(pure(pure('a')), pure(pure('b').setTactus(0.5))).stepJoin(), -- stepcat(pure('a'), pure('b').setTactus(0.5)), -- ), -- ); -- }); -- });