Enrutar código a una carpeta

Good afternoon;
I am in a code where I need to write a path to a sound file. To write to a folder with several files I use ‘entries.collect’ as follows:

‘’’
~bufPath = PathName.new(thisProcess.nowExecutingPath).parentPath ++ “sounds/”;

b = PathName.new(~bufPath).entries.collect({
arg pathname;
Buffer.read(s, pathname, fullPath);
})
‘’’
Now, I guess is that a bit silly question excuse my ignorance, but how to write the code for a single audio file.

You can just write

b = Buffer.read(s, "path/to/soundfile");

Then b will just be the single buffer instead of an array of buffers.

If you are using the default SC editor, you can drag a sound file from disk into the editor window and it will insert the full path as a string automatically.

Hello, thank you for replying. I think I did not explain the question well, because I knew that option, so I apologize.
I need the path to always be the same where the code is located.for example, using the instance “thisProcess”.

The answer is already right there in the example… just concatenate the filename onto it using the +/+ operator. String | SuperCollider 3.12.2 Help

Delete PathName – you won’t need it for this simple case.

.entries and the do loop, also not needed for just one file, so delete those too.

hjh

I believe he’s trying to get to the folder next to the file, but because he’s already in the file, he has to go a level above his current executing path.

Is there a way to use thisProcess.nowExecutingPath along with pathMatch and the traditional .. or “path above” operator?

Ohhh… Rainer is right, I forgot dirname.

thisProcess.nowExecutingPath.dirname +/+ "theOtherFile.wav"

hjh

I’ve passed up .dirname so many times, I always felt it would act differently.

On Windows, a +/+ will still print a forward slash, among back slashes, unfortunately.

PathName is a safe cross-platform choice, but only when it isn’t mixed with methods performed on string objects, and outside of PathName’s scope.

Now, in the original post, I believe you state you are trying to write a soundfile, and you already know how to read them, correct?

I don’t work in this area often, but in the documentation, try making a search for the word “disk”.

In programming, I would tend to avoid assertions about the reliability of this or that method based on feelings about unspecified differences in behavior. I would be convinced by concrete failures that could be demonstrated.

Have you ever observed wrong behavior from dirname?

I don’t think there’s an alternative in any case. If I have a file ~/test/xyz.wav, then I could go from ~/test to ~ by writing ~/test/.. because .. is a virtual entry in the test directory. But you couldn’t apply .. to the file ~/test/xyz.wav because files don’t have directory entries, virtual or otherwise. AFAIK the only way is to strip off the filename, which is what dirname does.

True but, again, have you found concrete functional problems with this? If not, I would say there’s nothing unfortunate.

SC’s interaction with the file system treats / and \ interchangeably. You can write a path as "D:/audio/xyz.wav" or "D:\\audio\\xyz.wav" or "D:\\audio/xyz.wav" and they will all work. Many programming languages do likewise (Java for sure). SC is following an established convention here.

The implication here is that String methods related to paths are not cross-platform safe. In fact rather a lot of care has been taken to ensure safety!

If you can demonstrate bugs in the string methods, great! Then they can be fixed. But I have reservations about the suggestion not to use string methods because you kinda sorta feel like there must be something wrong even though you’ve never seen it.

hjh

I would be convinced by concrete failures that could be demonstrated.

I completely agree.

Have you ever observed wrong behavior from dirname?

I wouldn’t call it wrong.

I observed the following methods, in chronological order, over several years & used most of them fairly extensively:

<a PathName>.folderName // returns name w/o path

<a PathName>.filename // -> returns name w/o path

<a PathName>.filenameWithoutExtension // expected

<a PathName>.filenameWithoutDoubleExtension // what could go wrong?

<a String>.basename // follows convention

<a PathName>.parentPath // returns the full path...

<a PathName>.fullPath // returns the full path...

And also reading the doc’s for:

<a String>.dirname // explanation:

/* Return the directory name from a Unix Path */

Return the directory name from it’s unix path.”

Or return the short one, from the long one… it seems.

And so following this convention of behavior, when one ‘renames’ a directory…

I don’t feel slighted to admit that upon ascertaining .dirname with at least halfway reasonable judgement, I assumed it to follow the same conventional thread as I had been unraveling it…and I can clearly remember thinking: "I cannot fathom the light in which this would not work in the way that my retinas are burned & in particular.

And I was completely wrong… however, this lead me to <a String>.splitext… which lead to further innovation upon using this method… I’m still mostly satisfied with this.

You make excellent points, I usually agree with them completely, and you’re right to make them, they deserve to be made in the light of abstaining from what is clearly such prudent advice… thank you for everything before, & in advance.

And hopefully the thread author solved his original problem… I forgot to mention SoundFile to him, but I think he may just need to pre-allocate a buffer in the right frame-rate, or whatever… I believe his original code with .parentPath.entries, while perhaps less concise or poetic, was still adequate enough for the path handling side of things.

@twistin did you ever manage to solve your probem? There’s a few examples in the PathName documentation for reading soundfiles using classes FileDialog & Signal… and maybe wavetable, I believe.

Don’t forget to search for ‘disk’ in the offline documentation… and check your sample rate in ServerOptions.

You can use .defaultValues on the ServerOptions class directly, but it isnt a great method… instead or for your first time use:

ServerOptions.openCodeFile

…and you can see all of the default values straight from the class source, very clearly.


It’s a fair assumption, given the expected forms of behavior;)

I’ve used file & path methods fairly extensively over the years (since 3.6.x) & I’ve experienced at least a few of the improvements first-hand, when you mention:

… cross-platform safe. In fact rather a lot of care has been taken to ensure safety!

I know it’s a lot of hard work, and it’s all truly appreciated… I know it can be difficult… thank you to all the devs here.

And those tricks for mixing back & forward slashes… I had no idea that Java, C, or even SC was already there, I was impressed, & you definitely taught me something.

I still think adhering to the PathName and/or Document interface, and letting it do the work of OS file conversion can be a safe choice for new users who perhaps want to post something to sccode.org, without having to battle with cross-platform path handling… but it’s mostly up to one’s desire.

Here’s some tests that I ran recently… I don’t have the time to do much more, and there’s no outstanding or i.e. sharp implication, this is just FWIW & nothing in particular is necessarily wrong or incorrect:

f = (  "~/Desktop\\TEST.scd"  )  // true path is C:/Users/one/Desktop/TEST.scd 

((
	File.exists( f )  // -> false
	
	PathName( f )  // -> PathName(C:\Users\one/Desktop\TEST.scd)
	
	load ( f )   // file "~/Desktop\TEST.scd" does not exist.
	
	openOS ( f )  // Windows 'cannot find' alert
	
	openDocument ( f ) 	// opens immediately, closed before continuing:
))

((
	PathName ( f ) .fullPath ==  // C:\Users\one/Desktop\TEST.scd 
	
	(
		f = (  f . standardizePath  )	 // -> true
	)
))

((
	File.exists( f ) // -> true
	
	PathName( f ) // -> PathName(C:\Users\one/Desktop\TEST.scd)
	
	load ( f ) //  a Function
	
	openOS ( f ) // silently returns ( f ), nothing opened
	
	openDocument ( f ) // opens just like before
))

PathName & Document are both excellent classes, they never fail, and they call .standardizePath for you, which (I’m now understanding) can never occur automatically with String, because it’s closer to a literal, or explicit class of objects.

I still run into one particular bug, when .openOS does not work in Windows for special characters (specifically, the delta symbol… I believe it is still alt+J on OS X), and the Windows alert message will claim that the full path does not exist, where the special character (delta, in this case) is replaced with a very strange encoding or format of the character,… as if it was in an alien language, or something.

I can still use .mkdir .executeFile Document( ) PathName( ) etc. on the path with the special or misrepresented character (issue is on the OS side, I believe), and it may have been this confusion or OS failure that led me to warn about the cross-platform incompatibility when using String, in the first place, which @jamshark70 demonstrated is mostly false.

I can only firmly attest that : "/path/to/file_with_a_special_character.scd" does not work with .openOS for the Windows platform only (if anyone could test the others) , at the moment.

I will post it as one of the issues in the official repo soon… I realize how important it is.

Please do – a couple of years ago, there were many problems with conversions of string encoding between Windows file system functions and SC’s internal representation (one of the varieties of Unicode… I won’t try to say more than that because at that time, I had said something about “Unicode encoding” and got my hand slapped… I only know, then, that encoding is far too complex and easy to mess up). Virtualdog (no longer an active developer) caught most of the places that need an explicit conversion function, but might have missed this one (understandable, since there were a lot of places).

OK, fair enough – in fact, in a github thread once, I had suggested dropping PathName and focusing on the string methods, but other developers’ opinion was that it would be better to deprecate the string methods and put everything into PathName, so that there is an object that indicates the string’s purpose.

I find that fairly convincing, though I think if we move in that direction, then PathNames should be made usable everywhere.

E.g.

p = PathName(Platform.resourceDir +/+ "sounds/a11wlk01.wav");

File.exists(p);
ERROR: Primitive '_FileExists' failed.
Wrong type.

s.boot;

b = Buffer.read(s, p);

FAILURE IN SERVER /b_allocRead wrong argument type

If it’s a valid complaint that one must call .standardizePath on a string path explicitly (and if it’s valid to consider PathName to be better because it does that for you), then IMO it’s an equally valid complaint that you must then call .fullPath in order to use the PathName anywhere that it actually matters.

So…

+ File {  // override
	*exists { arg pathName;
		_FileExists
		// ^this.primitiveFailed
		^this.exists(pathName.fullPath)
	}
}

+ PathName {
	asControlInput { ^this.fullPath }  // OSC bundle conversion
}

+ Buffer {  // override
	allocReadMsg { arg argpath, startFrame = 0, numFrames = -1, completionMessage;
		this.cache;
		path = argpath;
		this.startFrame = startFrame;
		^["/b_allocRead", bufnum, path.asControlInput, startFrame.asInteger, (numFrames ? -1).asInteger, completionMessage.value(this)]
	}
}

With those changes, the above examples are fine (though it would be better to have a more descriptive error in *exists, but, eh, not this morning).

PathName should also be made more convenient, e.g.:

// now:
b = Buffer.read(s, thisProcess.nowExecutingPath.dirname +/+ "xyz.wav");

// post-deprecation
// PathName seems *not* to have a method to create an instance
// relative to the current document, btw
b = Buffer.read(s, (PathName(thisProcess.nowExecutingPath).pathOnly +/+ "xyz.wav").fullPath);

I might be forgiven for finding the latter to be both inconvenient and pedantic. What actually is the value-add? You type more but there’s no gain in functionality or expressivity.

Now, it would be better if you could do e.g. b = Buffer.read(s, PathName.relativeToExecutingPath("xyz.wav")) (and not have to call fullPath explicitly). This would be more expressive and more convenient.

TL;DR PathName might be the way to go in the future, but I don’t think it’s ready yet.

hjh

Excellent… & as always, thank you.


I wouldn’t say either of those complaints deserves to be made… the true nature of those tests was solely aimed towards furthering development.

I can’t debate the ideal class source implementation at any great length, however, at the moment I fully appreciate the existing separation between PathName , File , UnixFile , Archive , String , and even Process & Platform.

@VIRTUALDOG did a lot of great things, you both do.

Thanks for everything.


As a last note, I agree there could be some finer improvements made in this area, and there is a certain natural frustration, when a PathName fails to understand what is clearly a path name…

I think the complaints are fair – the ideal would be to finish the interfaces and make them fully usable!

There’s a lot of good stuff in PathName but I feel it’s a bit inconsistent… I’d love to see the improvement that there’s room for

hjh