Home › Forums › General › Programming › saving/loading data to a file
- This topic has 47 replies, 8 voices, and was last updated 7 years, 10 months ago by goodweather.
-
AuthorPosts
-
February 17, 2013 at 11:25 am #6459
Stille the same error (see attachment in message above). Probably I use the wrong parameters in ‘replaceWithData(…)’, but I don’t really understand what ‘bool replaceWithData(LFile&, MemoryBlock const&)’ or ‘bool replaceWithData(File const&,void const*,int)’ means. I guess ‘bool‘ means the result is true or false, and ‘int‘ means the number of bytes in de data, but the rest?
Strange thing (at least to me) is also that this panel starts, when loaded, with a dialog window asking to save the file. When I cancel the panel is further loaded. My intention was to start saving (or loading) a file when a certain button is clicked.
The whole idea behind all this is that my device does allow to change the name of a what is called ‘performance’ (meaning a set of sounds and effect settings) but there is no way of retrieving this name (at least it is not documented AFAIK). So I want to save this changed name in a file and load (and show) it when needed.
March 1, 2013 at 6:42 pm #6790How can I access a folder inside user Application Data Directory?
tempBankFile = File.getSpecialLocation(File.userApplicationDataDirectory):getChildFile
(String(fileBankName))
March 1, 2013 at 10:04 pm #6795How can I access a folder inside user Application Data Directory?
tempBankFile = File.getSpecialLocation(File.userApplicationDataDirectory):getChildFile
(String(fileBankName))
Yeah that will work, in my console it says:
>>> t = File.getSpecialLocation(File.userApplicationDataDirectory):getChildFile ("blah") console (t:getFullPathName()) C:\Users\atom\AppData\Roaming\blah
March 1, 2013 at 10:57 pm #6797I think I wasn’t too clear.
I want to save a file in AppData\Whatever\file. With the code posted above the file is saved in AppData, not in AppData\Whatever.
I don’t know how to get to \Whatever folder.
March 1, 2013 at 11:11 pm #6803The same way, you can specify a relative path as stated here:
http://www.rawmaterialsoftware.com/juce/api/classFile.html#a4fcc888d3e82659859ceb3e792d86cddbut you need to check if all elements of your path (directories) are created and writable to be sure you can save to that place.
June 2, 2013 at 9:06 am #9483Hey Atom, since the code above is several months old would you mind updating your example script to save data to a file? This would be a good one to include with ctrlr as an example panel!
Thank you!
Monstrum Media | Music, Sound & Software Design, Chicago / San Francisco listen
June 11, 2013 at 7:45 am #9819Just pinging for my last post here.. if something up on http://svn.code.sf.net/ demonstrates saving a string to a file I’m not just not seeing it.
Monstrum Media | Music, Sound & Software Design, Chicago / San Francisco listen
June 11, 2013 at 9:03 am #9821I don’t see it there, i’ll create one at work and post it today.
June 11, 2013 at 6:24 pm #9843An example panel is on sf.net. It should work with the latest nightly, but if you get any errors wait for a bugfix build i’ll be doing today or tomorrow. The file is called DEMO – Files.panel
June 12, 2013 at 11:36 pm #9890Thanks so much for posting that demo panel, atom. I’ve made major steps forward. Since my windows laptop has crapped out on me I’ve been developing using the latest OS X ctrlr revs and unfortunately instead of printing Lua errors if/when the y occur ctrlr just locks up and crashes so debugging stuff has been a bit tedious..
What I’m doing is getting every modulator’s value, printing them into a contentToSave field (just like your demo) then saving the contents of the contentToSave field to a text document. Works great, I can then load the text document and everything is there but I can’t do anything yet with the data I’m loading back from the txt file yet, I’m wondering if you could help me with this…
First, I’m successfully able to get, save and load the values into/from a txt file but the values are being grabbed as decimal values not hex. Here’s what I’m doing to get the values into a format that can be saved to a file:
--get values from some modulators and print them in soundDataDisplay label : soundDataDisplay:setText (""..panel:getModulatorByName("arpDirection"):getValue()) soundDataDisplay:appendText (" "..panel:getModulatorByName("arpRange"):getModulatorValue()) soundDataDisplay:appendText (" "..panel:getModulatorByName("arpTempo"):getModulatorValue())
I've apparently misplaced the braincells which I had kept this info – Question One: how do I get/store these values as hex, not dec?
Then after I save the value data to a text file I want to be able to recall them in a way that I can pull certain bytes from that data so I can then send those values to the appropriate modulators.. I want to load the text file into an object named “programData”, then pull bytes from it like so:
panel:getModulatorByName("Osc 1 Octave"):setValueMapped(programData:getByte(1), false) panel:getModulatorByName("Osc 1 Semitone"):setValueMapped(programData:getByte(2), false) panel:getModulatorByName("Osc 1 Detune"):setModulatorValue(programData:getByte(3), false, false, false)
Question Two: I’m forgetting what I need to do in order to convert the contents of the loaded text file into an object (string? memoryBlock?) so that I can reference a byte to pass to a modulator. What do I need to do here?
It’s been some time since i’ve done this kind of stuff in Lua, and like i mentioned debugging on a mac is a headache so any suggestions are greatly appreciated. I’m sure I’ll get a slap across the face for doing it the wrong way but it’s cool I can handle it 🙂
- This reply was modified 10 years, 10 months ago by msepsis.
- This reply was modified 10 years, 10 months ago by msepsis. Reason: emphasized my questions needing answers
Monstrum Media | Music, Sound & Software Design, Chicago / San Francisco listen
June 12, 2013 at 11:48 pm #98931. don’t write your data to a label it’s not a good thing, i did that to demonstrate that the data is there, but don’t do setText(), it’s very slow CPU wise and generally it’s not needed
2. keep your data in Lua tables
3. for a nice set of dump/send utilities have a look at Demo – Data dump utilities, there are 2 functions that read the panel state to a MemoryBlock that you can write to a file (just like in the Demo – Files example), and there is a function that reads a MemoryBlock and sets the panel state from it
4. If you need to, write your values to a Lua table that’s indexed with numbers, like so
myTable = {} myTable[1] = panel:getModulatorByName("w00f"):getValue() myTable[2] = panel:getModulatorByName("w00f"):getValue() myTable[3] = panel:getModulatorByName("w00f"):getValue() myTable[4] = panel:getModulatorByName("w00f"):getValue()
then convert that table to a MemoryBlock
mb = MemoryBlock (myTable)
and write that to a file, do this in reverse to get the values
i’m sure there are other ways to do that, if you like some cross-version safety i’d write my stuff to a XML file using the ValueTree or XmlDocument/XmlElement classes, then you get your data in some nice textual representation that people can edit later.
there also ZipFile classes that let you compress/decompress files if you use XML and the files get too big.
A bit more info on Lua tables is in the thread: http://ctrlr.org/forums/topic/incoming-midi-parsing-efficiency-question/
June 12, 2013 at 11:55 pm #9894To convert a MemoryBlock to a hex string use toHexString(1) method (the 1 as the parameter is the grouping parameter for output)
a MemoryBlock can be constructed from a hex string ex:
mb = MemoryBlock ("f0 f1 f2 f3 f7") console (mb:toHexString(1))
June 13, 2013 at 12:54 am #9897Thank you atom, that was a very clear explanation. Locking myself into a room with the record light on to knock this out now 🙂
quick follow up question, do we still need to use getValueMapped or is that now getvalue? (for modulators with custom values), then for just generic sliders we still use getModulatorValue?
- This reply was modified 10 years, 10 months ago by msepsis. Reason: question about getmapped/getValueMapped/getModulatorValue
Monstrum Media | Music, Sound & Software Design, Chicago / San Francisco listen
June 13, 2013 at 2:55 am #9901so close. ctlrlr is locking up/crashing when i go to save my params as a txt file..
part one:
http://pastebin.com/4rfK7s5p
is working. I get in the console my parameter values in hex.part two:
http://pastebin.com/39AKxQwZ
fails. ctrlr locks and crashes, no messages indicating what the problem is.I’ve got all of the components involved with setting the path on my panel, so i dont think its that stuff. really all i did in the second script was replace this line:
textToWrite = panel:getLabelComponent(“contentToSaveL”):getText()with this line:
textToWrite = mySoundMemory:toHexString(1)Had it all in one script but the mac crash handicap led me to split it out to two steps. One to get the params, verify in console, second to save the memory block to a file.
NOW off to watch the blackhawks kick the bruins ass 🙂
Monstrum Media | Music, Sound & Software Design, Chicago / San Francisco listen
June 13, 2013 at 9:17 am #9903getValue is an alias to getModulatorValue
getModulatorValue is an alias to getValueNonMapped
and you still need to use getValueMapped if you have mapped values in your modulator (combox, lists, buttons), it depends on what value do you want.
June 13, 2013 at 9:21 am #9904In the second part, how i mySoundMemory variable initialized, you added that to a my example script, but it needs to have a value, it’s not initialized in the method anywhere, the assumption that it’s global is wrong unless you know exactly what you are doing.
June 13, 2013 at 9:06 pm #9915getValue is an alias to getModulatorValue
getModulatorValue is an alias to getValueNonMapped
is that a typo? You’re saying getValue = getValueNonMapped. I’m assuming you meant “getValue is an alias to getvalueMapped” . . .
Monstrum Media | Music, Sound & Software Design, Chicago / San Francisco listen
June 13, 2013 at 9:10 pm #9916In the second part, how i mySoundMemory variable initialized, you added that to a my example script, but it needs to have a value, it’s not initialized in the method anywhere, the assumption that it’s global is wrong unless you know exactly what you are doing.
I gave “mySoundMemory” a value in the first script in this line:
--CONVERT "mySound" TABLE TO MEMORY BLOCK: mySoundMemory = MemoryBlock (mySound)
When I have both the first part and the second part in one script together I still get a crash/lockup. mySoundMemory should have a value whether it was given a value in this script or some other script unless I define it as a local variable to that method.. right? So what am I missing? I’m still not getting what I’m doing wrong here.
Monstrum Media | Music, Sound & Software Design, Chicago / San Francisco listen
June 13, 2013 at 9:45 pm #9917getParameters = function(mod, value) --PUT ALL MODULATOR VALUES INTO "mySound" TABLE: mySound = {} mySound[1] = panel:getModulatorByName("arpDirection"):getValue() mySound[2] = panel:getModulatorByName("arpRange"):getValue() mySound[3] = panel:getModulatorByName("arpTempo"):getValue() mySound[4] = panel:getModulatorByName("envDecay"):getValue() mySound[5] = panel:getModulatorByName("envRelease"):getValue() mySound[6] = panel:getModulatorByName("envSustain"):getValue() mySound[7] = panel:getModulatorByName("holdNote"):getValue() mySound[8] = panel:getModulatorByName("lfoDepth"):getValue() mySound[9] = panel:getModulatorByName("lfoShape"):getValue() mySound[10] = panel:getModulatorByName("lfoSpeed"):getValue() mySound[11] = panel:getModulatorByName("lfoTarget"):getValue() mySound[12] = panel:getModulatorByName("localControl"):getValue() mySound[13] = panel:getModulatorByName("modWheel"):getValue() mySound[14] = panel:getModulatorByName("oscGlide"):getValue() mySound[15] = panel:getModulatorByName("oscShape"):getValue() mySound[16] = panel:getModulatorByName("oscTune"):getValue() mySound[17] = panel:getModulatorByName("oscWave"):getValue() mySound[18] = panel:getModulatorByName("vcfKeytrack"):getValue() mySound[19] = panel:getModulatorByName("vcfCutoff"):getValue() mySound[20] = panel:getModulatorByName("vcfEnvMod"):getValue() mySound[21] = panel:getModulatorByName("vcfResonance"):getValue() mySound[22] = panel:getModulatorByName("vibrato"):getValue() --CONVERT "mySound" TABLE TO MEMORY BLOCK "mySoundMemory: mySoundMemory = (MemoryBlock(mySound)) console (mySoundMemory:toHexString(1)) if panel:getBootstrapState() then return end fileToWrite = utils.saveFileWindow( "Save content as text", File.getSpecialLocation(File.userHomeDirectory), "*.txt", true ) if fileToWrite:existsAsFile() == false then if fileToWrite:create() == false then utils.warnWindow ("File write", "The destination file does not exist, and i can't create it") return end end -- GET FILE PATH: panel:getLabelComponent("lastFileWritePathL"):setText ("> "..fileToWrite:getFullPathName()) -- WRITE "mySoundMemory" MEMORY BLOCK TO FILE: if mySoundMemory:length() == 0 then utils.warnWindow ("Data to write", "There is no data to write, we'll default to \"OK\"") mySoundMemory = "OK" end if fileToWrite:replaceWithText (mySoundMemory, false, false) == false then utils.warnWindow ("File write", "Failed to write data to file: "..fileToWrite.getFullPathName()) end end
Is what I’ve got all in one script, your suggestion earlier said to get modulators, put them in a table, convert the table to a memory block, then write that memory block to a file. That’s precisely what I’m doing in the code above… I think what I’m not getting clearly is exactly how to put that memory block into the file. That’s the only part your example doesnt show and your suggestion didn’t explicitly cover. Ctrlr locks up when I run the script above but I do see the correct values in my memoryblock at the console, I do get the text file where I tell it to go except the text from my memory block is not in the text file as it should be.
Monstrum Media | Music, Sound & Software Design, Chicago / San Francisco listen
June 13, 2013 at 9:59 pm #9918Well you are doing it wrong
1. there is an example method for binary data in “saveContentAsData” method (you got hung up on the text version)
2. the method says “replaceWithText” and you are passing a MemoryBlock to it (again look at the saveContentAsData method to see the difference)
if fileToWrite:replaceWithText (mySoundMemory, false, false) == false then utils.warnWindow ("File write", "Failed to write data to file: "..fileToWrite.getFullPathName()) end
apart from that it looks good, i again encourage you to look at the DEMO – Data dump utilities, in there you will see that all your lines of code
mySound = {} mySound[1] = panel:getModulatorByName("arpDirection"):getValue() mySound[2] = panel:getModulatorByName("arpRange"):getValue() mySound[3] = panel:getModulatorByName("arpTempo"):getValue() mySound[4] = panel:getModulatorByName("envDecay"):getValue() --etc
can be replaced with one line and you get the MemoryBlock as a result with all the data you need, ready to write
data = panel:getModulatorValuesAsData("modulatorCustomIndex", 1, false)
-
AuthorPosts
- The forum ‘Programming’ is closed to new topics and replies.