konnakol 0.1.0.0 → 0.2.0.0
raw patch · 3 files changed
+116/−48 lines, 3 filesdep ~base
Dependency ranges changed: base
Files
- Konnakol/Define.hs +96/−44
- README.md +18/−2
- konnakol.cabal +2/−2
Konnakol/Define.hs view
@@ -1,16 +1,10 @@ module Konnakol.Define where -import Sound.Tidal.UI -import Sound.Tidal.Pattern - -import System.Random -import Data.String +import Sound.Tidal.Context hiding (s,n) +import System.Random ( getStdGen, Random(randomR), StdGen, mkStdGen ) +import Data.String ( IsString(fromString) ) import Data.List ( findIndex, intercalate, intersperse, isPrefixOf, tails ) import System.CPUTime () -import qualified Data.Map.Strict as K -import Sound.Tidal.Context (slow, cat, sound) -import GHC.Num (Num(fromInteger)) -import GHC.Real (Integral(toInteger)) -- | BeatCount consists of the three ways in counting a cycle. Dhruta is typically 2 beats, while -- Anudhruta is a single beat. The Jati of the Thala defines the Dhruta @@ -26,12 +20,19 @@ newtype Thala = T [BeatCount] deriving (Read) -- | Standard 7 thalas in the Suladi Sapta Thala system +dhruva::Thala dhruva = T [Laghu, Dhruta, Laghu, Laghu] +matya::Thala matya = T [Laghu, Dhruta, Laghu] +rupaka::Thala rupaka = T [Dhruta, Laghu] +jhampe::Thala jhampe = T [Laghu, Dhruta, Anudhruta] +thriputa::Thala thriputa = T [Laghu, Dhruta, Dhruta] +atta::Thala atta = T [Laghu, Laghu, Dhruta, Dhruta] +eka::Thala eka = T [Laghu] -- | Define display of Thala based on that of the BeatCount @@ -101,8 +102,8 @@ showFinalThala :: JatiGati -> Thala -> JatiGati -> String showFinalThala jati thala gati = let a = show thala - b = " (" ++ show ( calculateCount jati thala) ++ ")" - c = " <" ++ show (fromEnum gati )++ ">" + b = " (" ++ show ( calculateCount jati thala) ++ ") " + c = " <" ++ show (fromEnum gati )++ "> " in a ++ b ++ c -- | Get the Counts per beat in a certain thala in a particular gati @@ -133,7 +134,7 @@ getRepresentation ((K x):y:xs) jati thala pos = let (a,b) = getStringComp y jati thala (K x) pos in "<" ++ show (fromEnum x) ++ ">" ++ a ++ getRepresentation xs jati thala b -getRepresentation _ _ _ b ="" +getRepresentation _ _ _ _ ="" -- | Driver function for getting a virtual representation of a composition, after validation getStringComp :: Comp->JatiGati->Thala->Comp->Int-> (String, Int) @@ -154,9 +155,9 @@ -- | Core function in obtaining string from Composition convToList :: [([Syllable], Int)] -> Int ->JatiGati-> [Syllable] -convToList [] maxs g= [] +convToList [] _ _= [] convToList listas maxs g = - concatMap (\(x,s)-> concatMap (\t -> t:replicate (div maxs (getCountPerBeat g s) -1) Gdot) x) listas + concatMap (\(x,d)-> concatMap (\t -> t:replicate (div maxs (getCountPerBeat g d) -1) Gdot) x) listas -- | Final display of a thala in lines with proper subdivisions finalDisp :: [Syllable] ->Thala -> [Int] -> Int ->Int->[String]-> String @@ -215,7 +216,7 @@ (d, e) = genPhrase4Me (x - y) c in if y > x - y then (d ++ b, e) else (b ++ d, e) else let (pha, c) = phraseGenerator (div x factor) gen - b = concatMap (\x->x:replicate (factor - 1) Gdot) pha + b = concatMap (\t->t:replicate (factor - 1) Gdot) pha in (b,c) in (one, two) @@ -240,6 +241,7 @@ mohrad Sankirna = [Tha, Lan, Gdot, Gu, Dhin, Gdot, Thak, Gdot, Tha, Lan, Gdot, Gu, Dhin, Gdot, Dhin, Gdot, Gdot, Gdot] -- | Define one of the final constants used in the Mohra +mohraC1::JatiGati -> [Syllable] mohraC1 Chaturasra = [Tha, Lan, Gdot, Gu, Dhin, Gdot, Gdot, Gdot] mohraC1 Tisra = [Tha, Lan, Gdot, Gu, Dhin, Gdot, Thak, Gdot, Dhin, Gdot, Gdot, Gdot] mohraC1 Khanda = [Tha, Lan, Gdot, Gu, Dhin, Gdot, Thak, Gdot, Dhin, Gdot] @@ -247,6 +249,7 @@ mohraC1 Sankirna = [Tha, Lan, Gdot, Gu, Dhin, Gdot, Gdot, Gdot, Gdot] -- | Define the constant used to end the Mohra +mohraC2 :: JatiGati -> [Syllable] mohraC2 Tisra = concat (replicate 3 [Tha, Lan, Gdot, Gu, Dhin, Gdot, Thak, Gdot, Dhin, Gdot, Thak, Gdot, Dhin, Gdot, Gdot, Gdot, Gu, Gdot]) ++ replicate 6 Gdot mohraC2 Chaturasra =concat (replicate 3 [Tha, Lan, Gdot, Gu, Dhin, Gdot, Thak, Gdot, Dhin, Gdot, Gdot, Gdot]) ++ replicate 4 Gdot mohraC2 Khanda = concat( replicate 3 [Tha, Lan, Gdot, Gu, Dhin, Gdot,Thak, Gdot, Dhin, Gdot, Thak, Gdot, Dhin, Gdot, Gu, Gdot]) ++ [Gdot, Gdot] @@ -263,9 +266,9 @@ -- | To get the appropriate separations for a required mohra generation getMohraSeparation::Int->JatiGati->[Int] getMohraSeparation count gati = - let snd = length $ mohrad gati - fst =div (count - 2*snd) 2 - in [fst, snd, fst, snd] + let scnd = length $ mohrad gati + frst =div (count - 2*scnd) 2 + in [frst, scnd, frst, scnd] -- | To generate a Mohra on the basis of the jati, thala and gati genMohra::JatiGati->Thala->JatiGati->StdGen->[Syllable] @@ -274,18 +277,16 @@ phd = mohrad gati overAllCount = if calculateCount jati thala<= 4 then 2*calculateCount jati thala else calculateCount jati thala - [a,b,c,d] = getMohraSeparation (getCountPerBeat gati sp*overAllCount) gati + [a,b,_,_] = getMohraSeparation (getCountPerBeat gati sp*overAllCount) gati (pha, gen1) = if gati==Chaturasra || gati == Misra || gati == Sankirna|| mod a 2 ==1 then genPhrase4Me a gen else genPhrase4Me (div a 2) gen pham = if gati == Chaturasra || gati == Misra || gati == Sankirna|| mod a 2 == 1 then pha else intersperse Gdot pha ++ [Gdot] - (phb, gen2 ) = if gati==Chaturasra || gati == Misra || gati == Sankirna || mod a 2 == 1 then genPhrase4Me b gen else genPhrase4Me (div b 2) gen + (phb, _ ) = if gati==Chaturasra || gati == Misra || gati == Sankirna || mod a 2 == 1 then genPhrase4Me b gen1 else genPhrase4Me (div b 2) gen1 phbm = if gati == Chaturasra || gati == Misra || gati == Sankirna || mod a 2 == 1 then phb else intersperse Gdot phb ++ [Gdot] c1 = mohraC1 gati c2 = mohraC2 gati derMohra = concat [pham, phbm, pham, phd, pham, phbm, pham, phd, pham, phbm, pham, c1,pham, c1, pham,c2] in derMohra ---getRepresentation [K gati, C [(derMohra, sp)]] jati thala 0 - -- | To read the thala from user input getThala :: String->Thala getThala "Dhruva" = dhruva @@ -295,6 +296,7 @@ getThala "Thriputa" = thriputa getThala "Atta" = atta getThala "Jhampe" = jhampe +getThala _ = eka @@ -308,16 +310,17 @@ getGPh 6 = concat $ replicate 2 (getGPh 3) getGPh 7 = getGPh 4 ++ getGPh 3 getGPh 8 = getGPh 3 ++ getGPh 5 +getGPh _ = error "Undesired length" -- composing a smaller subpattern for a Korvai without the extra gap getSub:: Int-> StdGen -> ([Syllable], [JustNums]) -getSub sum gen = - let vals1 = [([x, x + d..(x + (n -1)*d)],g) | x <- [1,2..(div sum 3)], d <- [2,3..8], g<- 0:[2,3..8], n <-[3,4, 5], n*x + (n-1)*g + (div (n*(n-1)) 2) *d ==sum] +getSub s gen = + let vals1 = [([x, x + d..(x + (n -1)*d)],g) | x <- [1,2..(div s 3)], d <- [2,3..8], g<- 0:[2,3..8], n <-[3,4, 5], n*x + (n-1)*g + (div (n*(n-1)) 2) *d ==s] vals2 = map (\(a,b) -> (reverse a,b)) vals1 vals = vals1 ++ vals2 (pos, gen2 ) = randomR (0, length vals - 1) gen :: (Int, StdGen) - (phs, gp) = if null vals then ([sum],0) else vals !! pos - (ph1, newgen, nList) + (phs, gp) = if null vals then ([s],0) else vals !! pos + (ph1, _, nList) | minimum phs > 15 = let fl = map (`getSub` gen2) phs fl1 = map fst fl @@ -333,14 +336,14 @@ -- | To generate the purvardha for a given length for the Korvai getPurvardha::Int->StdGen->([Syllable], StdGen, [JustNums]) -getPurvardha sum gen = - let vals1 = [([x, x + d..(x + (n -1)*d)],g) | x <- [1,2..(div sum 3)], d <- [2,3..8], g<- [2,3..8], n <-[3,4, 5], n*x + n*g + (div (n*(n-1)) 2) *d ==sum] +getPurvardha s gen = + let vals1 = [([x, x + d..(x + (n -1)*d)],g) | x <- [1,2..(div s 3)], d <- [2,3..8], g<- [2,3..8], n <-[3,4, 5], n*x + n*g + (div (n*(n-1)) 2) *d ==s] vals2 = map (\(a,b) -> (reverse a,b)) vals1 - vals3 = [([x,x,x], g) | x<- [1,2..(div sum 3)], g<- 0:[2,3..8], 3*x + 3*g == sum] - vals4 = [(map (\k -> x*d^k) [0,1..(n-1)], g) | x <- [1,2..(div sum 3)] , d <- [2,3,4,5], g <- [0,2,3,4,5], n <- [3,4,5], x*(div (d^n - 1) (d -1)) + n*g == sum ] + vals3 = [([x,x,x], g) | x<- [1,2..(div s 3)], g<- 0:[2,3..8], 3*x + 3*g == s] + vals4 = [(map (\k -> x*d^k) [0,1..(n-1)], g) | x <- [1,2..(div s 3)] , d <- [2,3,4,5], g <- [0,2,3,4,5], n <- [3,4,5], x*(div (d^n - 1) (d -1)) + n*g == s ] vals = vals1 ++ vals2 ++ vals3 ++ vals4 (pos, gen2 ) = randomR (0, length vals - 1) gen :: (Int, StdGen) - (phs, gp) = if null vals then ([sum],0) else vals !! pos + (phs, gp) = if null vals then ([s],0) else vals !! pos (ph1, newgen, nList) | minimum phs > 15 = let fl = map (`getSub` gen2) phs @@ -386,7 +389,7 @@ (totPur', gen1) = randomR (div (overallCount - 50) 2, div (overallCount - 15) 2) gen :: (Int, StdGen) totPur = totPur' * 2 totUtt = overallCount - totPur - (purva, gen2, nList) =getPurvardha totPur gen1 + (purva, _, nList) =getPurvardha totPur gen1 (uttara, nList2) = if even totUtt && totUtt >=32 then getUttarVarying totUtt else getUttar totUtt in (purva ++ uttara , nList ++ nList2) @@ -403,7 +406,7 @@ genComp::[UIComp] -> JatiGati -> Thala ->StdGen -> [Comp] genComp ((Tc x):y ) jati thala gen =K x:genComp y jati thala gen genComp ((Ph t:y)) jati thala gen = - let b = foldl (\(acc, gen1) (p,q) -> ((fst (genPhrase4Me p gen),q):acc, snd(genPhrase4Me p gen))) ([], gen) t + let b = foldl (\(acc, gen1) (p,q) -> ((fst (genPhrase4Me p gen1),q):acc, snd(genPhrase4Me p gen1))) ([], gen) t a = fst b in C a:genComp y jati thala (snd b) genComp ((Gp t: y)) jati thala gen = @@ -469,6 +472,7 @@ bool3 = mod totsum avarta == 0 in bool1 && bool2 && bool3 +main :: IO() main = do value1 <- getLine value2 <- getLine @@ -490,7 +494,7 @@ getRT ((K x):y:xs) jati thala pos = let (a,b) = getSCT y jati thala (K x) pos in a ++ getRT xs jati thala b -getRT _ _ _ b ="" +getRT _ _ _ _ ="" -- | Driver function for getting a virtual representation of a composition, after validation getSCT :: Comp->JatiGati->Thala->Comp->Int-> (String, Int) @@ -536,7 +540,7 @@ showT (Ri:xs) = "c " ++ showT xs showT (Ka:xs) = "ka " ++ showT xs showT (Tham:xs) = "ac " ++ showT xs -showT (Thak:xs) = "thak " ++ showT xs +showT (Thak:xs) = "c " ++ showT xs showT (Dhim:xs) = "dhin " ++ showT xs showT (Nam:xs) = "nam " ++ showT xs showT (Mi:xs) = "c " ++ showT xs @@ -556,14 +560,62 @@ y = (length.filter (=='[') ) x in (slow (fromInteger $ toInteger y) $ sound (fromString x)) --- btfix :: [(Int, Pattern a)] ->Pattern a --- btfix x = let --- a = map fst x --- b = foldl (\accum y -> div (accum * y) (gcd accum y)) (head a) a --- c = map (\y -> slow (fromInteger $ toInteger $ div b (fst y)) (snd y)) x --- in cat c +-- Method to convert a composition into a pattern Sequence +-- Converting getRT would be pretty easy I guess in this regard +-- | Representing Compositions with changing speeds as lists of lists of syllables +getSeqRep:: [Comp] -> JatiGati ->Thala ->Int->[[Syllable]] +getSeqRep ((K x):y:xs) jati thala pos = + let (a,b) = getSCTSeq y jati thala (K x) pos + in a ++ getSeqRep xs jati thala b +getSeqRep _ _ _ _ =[] --- How do I concatenate a series of patterns into a single pattern? --- Once I do that I can perhaps obtain one single pattern containing all thse patterns --- So using this compositions wth varying times can be composed. +-- | Driver function for getting a list representation of a composition, after validation +getSCTSeq :: Comp->JatiGati->Thala->Comp->Int-> ([[Syllable]], Int) +getSCTSeq (C k) jati (T thala) (K gati) pos = + let maxS = maximum $ map snd k + countPerBeat = getCountPerBeat gati maxS + b = calculateCount jati (T thala) + countPerAvarta = countPerBeat * b + a = convToList k countPerBeat gati + d = + --if mod (length a) countPerBeat == 0 then + let c = replicate (calculateCount jati (T thala)) countPerBeat + in (finalDTSeq a (T thala) c pos countPerBeat, pos + div (mod (length a) countPerAvarta) countPerBeat ) + --else ("Error", 0) + in d +getSCTSeq _ _ _ _ _ = ([[]],0) + +-- | Final display of a composition as a list of lists of syllables with proper subdivisions +finalDTSeq :: [Syllable] ->Thala -> [Int] -> Int ->Int-> [[Syllable]] +finalDTSeq s (T thala) arr n cPB= + if null s then [[]] + else let pos = mod n (length arr) + in take cPB s : finalDTSeq (drop (arr !! pos) s) (T thala) arr (n+1) cPB + +-- | Function which takes a list of list of syllables and converts each list to a Sequence +-- getSeqfromKon :: [[Syllable]] -> Rational -> [Sequence Syllable] +-- getSeqfromKon [] _ = [] +-- getSeqfromKon (x:xs) durat = +-- let y = durat / realToFrac (length x) +-- a = map (\t -> if t == Gdot then Gap y else Atom y t) x +-- in Sequence a : getSeqfromKon xs durat + +-- -- | Function to return a desired Korvai in Sequence notation +-- sequenceK :: JatiGati -> Thala -> JatiGati -> StdGen ->Sequence Syllable +-- sequenceK jati thala gati gen = +-- let x = getSeqRep [K gati, C[(fst(genKorvai jati thala gati gen), getMohraSpeed gati - 1)]] jati thala 0 +-- y = getSeqfromKon x 1 +-- in Sequence.unwrap $ Sequence y + +-- -- | Function to return a desired Mohra in Sequence notation +-- sequenceM :: JatiGati -> Thala -> JatiGati -> StdGen -> Sequence Syllable +-- sequenceM jati thala gati gen = +-- let x = getSeqRep [K gati, C [(genMohra jati thala gati gen, getMohraSpeed gati - 1)]] jati thala 0 +-- y = getSeqfromKon x 1 +-- in Sequence.unwrap $ Sequence y + + +-- Mridangam samples (c) Arthur Carabott, distributed under a CC-BY-SA license https://creativecommons.org/licenses/by-sa/4.0/ + +
README.md view
@@ -1,2 +1,18 @@-# gsoc-konnakol -Repository for Konnakol experiments during GSOC 2022 +# GSOC Konnakol + +Repository of experiments performed as a part of the Google Summer of Code 2022. + +Contributer : Aravind Mohandas +Mentor: Alex McLean + +To read more about Konnakol visit [here](ABOUT_KONNAKOL.md) + +To understand the datatypes and functions used, visit [here](HOW_TO_USE.md) + +To look at sample diagrams generated, visit [here](samplediags/) + +To launch a code and make music: [Visualising Konnakol Compositions - GSoC '22 Update 2](https://dev.to/aravindmohandas/visualising-konnakol-compositions-gsoc-22-update-2-16pc) + +## Audio Samples + +Mridangam samples (c) Arthur Carabott, distributed under a CC-BY-SA license https://creativecommons.org/licenses/by-sa/4.0/, performed by Harishankar V Menon.
konnakol.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: konnakol -version: 0.1.0.0 +version: 0.2.0.0 synopsis: Formalising the rules of Konnakol, an Indian percussional art form. @@ -39,7 +39,7 @@ type: exitcode-stdio-1.0 hs-source-dirs: test main-is: MyLibTest.hs - build-depends: base ^>=4.14.3.0 + build-depends: base ^>=4.15.1.0 source-repository head type: git