About itllallendintears

An(other) English eccentric.

MacBook Pro 2021 Review

Back in 2018 work gave me a new MacBook Pro. One would struggle to say that it was “well received“. That said, it was just a work machine. Plugging in an external screen and keyboard made it sort of tolerable… not really, just moving the mouse is enough to spin up the fans.

Work is work, but my main home machine was a late 2013 MacBook Pro that had none of the issues of the 2018 model… except it was old and slooow. It also stopped being able to upgrade to the latest o/s versions. The writing was on the wall…

<several weeks later>

The new machine is fine. The screen is amazing, the speakers impressive. Performance is kind of unbelievable – tasks like compiling ffmpeg which used to peg all cores for minutes are over before you’ve even noticed.

The case feels flimsy / thin. The bottom panel is especially flexible, the screen housing is better, but overall the case is a step down in quality / ruggedness. I know i’m not supposed to be trying to abuse it, but it feels too fragile!

The keyboard is only “okay”. It’s still too loud in a kind of “clunky” way that doesn’t inspire confidence in its longevity. The lack of contrast between the keys and the bed makes it harder to use in lowlight. Yes, i could turn on backlighting… but, no. Oh, and the TouchID “key” looks and feels out of place – not that the one on the 2018 model is anyway good / better. At least i’m using it on this machine and enjoying not having to type my password as often.

Unlike the 2016 debacle the above issues are more qualms / quibbles. If i’d been able to walk into the store and see / feel before buying, on balance, i’d probably still have bought one.

In short: still in mourning, and not sure i should have started dating again so soon.


Today i remembered the time i had to learn to reverse a articulated truck as a teenager. This was likely before getting a conventional driving license. All of which set me off on a search to see it was possible to find the related patent that my father was granted… and it is!

It’s Patent US4784066A, which is handily available on Google with all the diagrams, one of which is below.

Don’t remember much about truck drivng beyond the unfeasibly numerous low gears, ridiculously long clutch, and how it was impossible to see anything at the back. It might be that someone else lined the thing up and my job was only to slowly reverse onto the railway tracks to couple with the boogie (technical talk!)

Out there somewhere is a short segment on the project that appeared on Tomorrow’s World. Periodically i go looking for an archive, but the BBC gave up adding things long ago… having written all that, it seems terribly familiar, and makes me worry that i’m repeating myself!

PaulStretch on Apple Silicon in 2022

It’s become something of a tradition – will the PaulStretch code still work n years later? The answer invariably is, yes!

Clone from github:

% git clone https://github.com/paulnasca/paulstretch_cpp.git
Cloning into 'paulstretch_cpp'…
remote: Enumerating objects: 166, done.
remote: Total 166 (delta 0), reused 0 (delta 0), pack-reused 166
Receiving objects: 100% (166/166), 92.98 KiB | 2.58 MiB/s, done.
Resolving deltas: 100% (101/101), done.

Look at previous notes and install dependencies:

% sudo port install fltk
% sudo port install audiofile
% sudo port install libmad
% sudo port install portaudio
% sudo port install fftw-3-single
% sudo port install mxml

Apply the following patch to XMLwrapper.cpp

% git diff XMLwrapper.cpp
diff --git a/XMLwrapper.cpp b/XMLwrapper.cpp
index 1efb66e..8fe17ad 100644
--- a/XMLwrapper.cpp
+++ b/XMLwrapper.cpp
@@ -29,7 +29,7 @@ int xml_k=0;
 char tabs[STACKSIZE+2];
 const char *XMLwrapper_whitespace_callback(mxml_node_t *node,int where){
-    const char *name=node->value.element.name;
+    const char *name=mxmlGetElement(node);
     if ((where==MXML_WS_BEFORE_OPEN)&&(!strcmp(name,"?xml"))) return(NULL);
     if ((where==MXML_WS_BEFORE_CLOSE)&&(!strcmp(name,"string"))) return(NULL);
@@ -407,10 +407,10 @@ void XMLwrapper::getparstr(const char *name,char *par,int maxstrlen){
     if (node==NULL) return;
-    if (node->child==NULL) return;
-    if (node->child->type!=MXML_OPAQUE) return;
+    if (mxmlGetFirstChild(node)==NULL) return;
+    if (mxmlGetType(mxmlGetFirstChild(node))!=MXML_OPAQUE) return;
-    snprintf(par,maxstrlen,"%s",node->child->value.element.name);
+    snprintf(par,maxstrlen,"%s",mxmlGetText(mxmlGetFirstChild(node), NULL));

Generate the UI:

% fluid -c GUI.fl
% fluid -c FreeEditUI.fl

And compile:

% g++ -ggdb -Wno-return-type GUI.cxx FreeEditUI.cxx *.cpp Input/*.cpp Output/*.cpp `fltk-config --cflags` \
 `fltk-config --ldflags`  -laudiofile -lfftw3f -lz -logg -lvorbis -lvorbisenc -lvorbisfile -lportaudio -lpthread -lmad -lmxml -o paulstretch
GUI.cxx:661:23: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl]
        const char *outstr=control.Render(control.get_input_filename(),outfilename,type,intype,
1 warning generated.

Ignore the warning and run the thing!

% ./paulstretch &