Kara-Moon Forum
March 29, 2024, 08:50:37 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: You can go back to the main site here: Kara-Moon site
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Data in library (groove) files  (Read 4759 times)
sciurius
Sr. Member
****
Posts: 443



« on: July 22, 2019, 01:16:43 PM »

Refering to my RisingSun groove.

The file contains the groove definitions, and also song data. When MMA plays the file you will hear the song.

However, when using this file as a groove library, the song data should be ignored. A trivial way to obtain this is to split the file into "RisingSun.mma" (with grooves) and "RisingSunSong.mma" with the song.

Personally I'd prefer to be able to keep this together, just like the docs (Begin Doc  ... End Doc).

There are several ways to deal with this.

For example, MMA could define a macro, e.g. $_InLibrary and the song data could then be placed between If NDef $_InLibrary .. EndIf.

The attached patch implements the EndGrooves (just a suggestion) command. When this occurs in a library file, parsing ends and the rest of the file is skipped. Otherwise, the line is ignored and parsing continues.

Do you think this functionality (one way or another) is useful?

* endgrooves.patch.txt (1.38 KB - downloaded 201 times.)
« Last Edit: July 22, 2019, 01:33:46 PM by sciurius » Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #1 on: July 22, 2019, 04:41:40 PM »

I do think it's useful ... and I don't Smiley

The main problem is that MMA really doesn't differentiate between song and library (and init and include) files. They are all "just files" and are all processed in sequence. So your suggestion relies on "In a library" being true when (and only when) a groove is being defined is not the most robust Smiley Mixing existing library files with song files is not uncommon (see the example song files).

I you want to have some test data in your lib file -- which I think is a good idea, even though I don't do it -- might be to wrap the song stuff in a macro. Something like:

   ... groove stuff

   If Def $TESTING
     ... song stuff
   Endif

All we'd need to do that way is to agree on a standard macro name Smiley Much like (well, not really, but close enough) to what python does with __MAIN__.
Logged

My online life: http://www.mellowood.ca
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #2 on: July 22, 2019, 04:53:41 PM »

Opps, forgot to mention a method for setting the sentinel variable.

I have on my list of things to do to add command line macros, like the MMA_ENCODING, etc. Before trying thought is to permit anything in the form MMA_*** to be seen as an env variable on startup and have it automatically set in MMA. So, for the test wrapper we could have something like this on the command line:

    MMA_TESTING="" mma mylibfile.mma

And, then wrap the test code with $MMA_TESTING. Hmmm, or would that be $Testing??? Might make more sense to keep the stuff after the _ case insensitive?

Thoughts?
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #3 on: July 22, 2019, 05:29:22 PM »

We have $_LineNum, so why not add $_FileName (name of the current file) and $_SongFileName (name of the current song, as specified on the command line)?

This looks pretty solid to me (in macro.py):

       elif s == 'FILENAME':
            return str(gbl.inpath.fname)

        elif s == 'SONGFILENAME':
            return str(gbl.infile)


(or maybe return MMA.file.locFile(gbl.infile, None)?

A library file can then use:

   If EQ $_FileName $_SongFileName
        ... being used as a song ...
    Else
        ... being incuded somehow ...
    EndIf


Does that sound useful?
« Last Edit: July 22, 2019, 05:32:32 PM by sciurius » Logged
sciurius
Sr. Member
****
Posts: 443



« Reply #4 on: July 22, 2019, 05:39:14 PM »

thought is to permit anything in the form MMA_*** to be seen as an env variable on startup and have it automatically set in MMA.

Sounds nice. I would not make a difference between environment and command line, so

    MMA_Testing=1 mma ...

and

    mma -S Testing=1 ...

would both set variable TESTING to 1.
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #5 on: July 22, 2019, 06:01:14 PM »

I like the idea of $_FileName ... the libfile could do a self reference to the filename. I'll have a look at that later ... should be an easy fix Smiley (always do Smiley in case it's not so easy!). Thanks.
Logged

My online life: http://www.mellowood.ca
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #6 on: July 22, 2019, 06:59:27 PM »

Just one question on this. Should we strip off the path info?

Your suggestion gives me $_Filename of /usr/local/share/mma/lib/stdlib/fastblues.mma. Might be more useful to have just "fastblues"?

And, since you can compile either "test" or "test.mma" ... simple enough to do either way. My initial reaction is to strip both the path info and the .mma suffix.
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #7 on: July 22, 2019, 06:59:55 PM »

While on the topic of environment variables: why not (also) add a function to fetch arbitrary environment variables? E.g.

    Set a $( env("HOME") )

?
Logged
sciurius
Sr. Member
****
Posts: 443



« Reply #8 on: July 22, 2019, 07:23:58 PM »

Your suggestion gives me $_Filename of /usr/local/share/mma/lib/stdlib/fastblues.mma. Might be more useful to have just "fastblues"?

I don't think so. I really expect something called filename to return a filename.

Nevertheless the idea of having a macro that provides "fastblues" is interesting. I would call it $_Style, not filename. Style FastBlues consists of the grooves FastBlues, FastBluesWalk, FastBluesEnd, ....

And the library file could explicitly define the style with a "Style FastBlues" command...

And it could default to the file basename. Cute...

Quote
And, since you can compile either "test" or "test.mma"

Yes, using MMA.file.locFile(gbl.infile, None) is a good idea.

Quote
My initial reaction is to strip both the path info and the .mma suffix.

Then you would lose the distinction between /usr/local/share/mma/lib/stdlib/fastblues.mma (the library file) and fastblues.mma (the test program). And that's where it's all about.

Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #9 on: July 22, 2019, 08:51:49 PM »

Okay. Let me gel over this for a day. Gotta run off to some music practice stuff just now Smiley
Logged

My online life: http://www.mellowood.ca
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #10 on: July 23, 2019, 12:12:02 AM »

Would the following give enough options:

   $_Filename  ... filename of file being processed
   $_Filepath   ... same, but complete path (like -o give)
   $_Songname ... file specified when mma was called. Might be the same as $_Filename
   $_Songpath   ... complete path. Might be same as $_Filepath

All would have .mma there if the file has .mma.

Have a look a the filenames printed when you use -o on the command line.

Would that cover everything? Simple to do from this end.
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #11 on: July 23, 2019, 09:31:12 AM »

It surely covers about everything  Cheesy.

Personally I do not see an advantage of having $_FileName and $_FilePath, since $_FilePath gives all the info and it is easy to use $(...) to split the path and name parts, if needed.

Having said that, there seems to be a problem with $(...):

    print $( 'x'.split() )

prints ['x']

but this gives an error:

    print $( 'xx'.split() )

Illegal/Unknown operator 'xx' in $()

In general, you cannot use strings that contain two or more consecutive letters in $(...). This is due to the attempt to prevent unsafe code to execute.

Did you know there is a safe way to call eval() in python?

safeCmds = ['ceil', 'fabs', 'floor', ..., 'randint' ]
safeDict = dict([ (k, locals().get(k, None)) for k in safeCmds ])

def safe_eval(expr):
    try:
        return eval(expr, {"__builtins__":None}, safeDict)
    except:
        error("Illegal operation in '%s'." % expr)


Now you can only use the functions named in safeCmds.

It is easy to extend the list with private functions, e.g.

def safe_env(expr):
    if environ.has_key(expr):
        return environ.get(expr)

safeDict["env"] = safe_env


This provides a safe way to fetch environment variables in MMA programs:

    print $( env("HOME") )

May I humbly recommend the attached patch to safe_eval.py?

* safe_eval.patch.txt (1.3 KB - downloaded 214 times.)
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.066 seconds with 19 queries.