This week it rained a lot |
Three sisters |
Sounds in the blogsystem
Sunday 16 May
Hi, Here is another kind of blog compared to my usual blog style. A couple of years back, I was producing music. I liked it that much. I recall that when Mr. Trump became a White House resident, I took a break from producing music about that time. It was not an active break. It just faded out in nothing. Yes, it was his fault. No, I am kidding.
My time was filled with other things, such as planning for the new house. It has happened that I launched the DAW to look at all the knobs and have the feeling, “help, I don’t know what all these knobs are for.”
A couple of weeks ago, I decided to restart the music production again but not as intense as four or five years ago. This time more relaxed, and I hope to spend less time on it. I remember that five years ago, I also had the idea of writing about the process of creating music. Back then, it failed on little things such as that my blog was not working well. Another thing about writing about sounds is that it is difficult only to write words. You need to be able to add illustrations as well. Sound-illustrations.
So before I get into blogging about my music production, I decided to include sounds in my blog. Such as this sound here:
First, a small recap of my blog: It is a LAMP system. L is for Linux. The web server is Apache. The database is My SQL, and it is programmed in PHP. I programmed the whole system myself, and there is no WordPress involved. I blogged about creating the system. If you go back in time on my blog, you can find every step to create the blog. I documented large parts of how I did except the extensive security system I did not blog.
Besides the LAMP, I created a Python program to read word documents and convert them to blog posts for the blog. Herein lies a complete game-changer for me. I can write in Word, and that suits me very well. Then my conversion program does the conversion so that the blog can be published. If I have images, they are converted as well. If I insert a specially crafted table, I can display slideshows. When I had made the conversion program, it resized images with a lousy algorithm so that thumbnail images from that period look strange. Later I fixed the algorithm, but I did not go back and redo the old images. That is for another time.
This workflow is efficient, and that makes blogging fun. I increased my blogging considerably with this system. It is not uncommon for me to write between two and three thousand words per week and take around 20 photos.
Here is the core of the challenge with my new idea of blogging about producing music. It has to be incorporated into my current blog workflow.
If you are reading this, you might think that changing a blogging workflow to start blogging about music production is like starting a cooking recipe with “how to carve us a spoon.” You are right, but that does not matter. I feel this is the right way to go. When I have this, I can talk about my feelings about making music, what I learn when I compose music, and why I am doing it. I can teach you about how I go about music, and I can learn from myself. I find it very inspiring to blog about creative things, even if no one is listening. I can go back to what I wrote and what I tried, and the process becomes a timeline that in itself is part of the creative process.
So can you include sounds in a Word document? Yes, you can! In the Insert ribbon at the text section, you have an “Object…” option. Point to a sound file and include it.
With that, it should be possible to change my conversion program to handle sound files as well.
Another obstacle five or ten years ago was that it was hard to play sounds from a web page. With HTML5, this has become easier. So, I am told. I have not tried it yet. The last time I tried playing a sound from a web page, it wasn’t straightforward, but things improved this time. One had to use Flash to play sounds back then, which was not an option for me.
The conclusion is that I am starting my music production again, but blog about it this time. To do that, I need to play sounds, and for this is the possibility to play a sound necessary for my blog workflow. So that is what I am going to do now.
Tuesday 18 May 2021
As I usually do when trying to figure out what is stored in a Word document, I make a copy and change the extension to zip.
When the zip is extracted, I open the document.xml with a text editor Notepad++, but you can use any editor. The advantage is that I can prettify the XML, which is necessary (for me) to understand the structure.
The last sentence is “Such as this sound here.” Then comes this object in the XML. It is not giving away so much information about what it is about, but it has r:id=5. Can you see it? It is at the end of the third line from the bottom.
In “document.xml.rels” I find what that ID is referring to:
I need to look into embeddings/oleObject1.bin, so what do we have there? Well, it is an OLE object.
Pretty useless when opened in Notepad++.
That first character, though, tells me this is a standardized container for windows stuff. Old word documents also have that “D” character with a stroke through it. Also called crossed D or dyet. It was invented by a Serbian philanthropist named Đuro Daničić in 1878. I have no connections with that. For me, this character is the character you see when you open the old Microsoft Word documents in a text editor, or as in our case, an OLE file. Old Microsoft Word documents are some form of OLE files, but that is no longer important. These days the Microsoft Word starts with PK, and that is because they are zip files. Somewhere in the history of zipping, there was a program called PKZip, and apparently, it started the file format with those two letters.
So now we can start hammering on Google to get more into this. I am trying some searches.
I found out that I am dealing with a standard OLE wrapper. I am not good at these. It first looked like I had to port everything to a more Microsoft friendly programming language like c#, but then I came across this information:
https://stackoverflow.com/questions/32026416/extract-ole-object-word-document-from-ms-access
It looks like the file can be found in there somewhere.
To try this, I put up the original file and the bin file from the Word document; it looks like the beginning of the sound file can be found in the ole wrapper.
But where does it end?
There is junk at the end.
One way to continue this route is to experiment with more sound files and see how Word wraps these. Then, I need to teach my app to unwrap that!
Thursday 20 May
I wonder if someone made a tool that can do this for me on Python? That would be fantastic. I started searching on this, and there are several Python libraries to unwrap OLE files. Now I need to find one that is alive. I decided on trying oletools first. It has been around for a while and looks like it has a robust following. It is not entirely clear to me where the home directory is, but here are one oletools.
The installation went fine. I started on a little ole test program.
The result is not that much, but it is something.
I think I have three parts in the bin file. I try to open a stream to the first.
I find an example opening a stream https://medium.com/python4you/python-io-streams-in-examples-97d2c4367207.
After experimentation the entire evening and a bit into the night, I came up with this test program extracting the sound file from the bin file
Here below is the listing as text. I don’t remember how to mark this for code. It turned out that I talked about that on 7 August 2019. That is one year, nine months, and 14 days ago. I got a screenshot of creating the style Code that my blog program picks up and renders correctly.
Instead of just doing this, I go and update my Normal.dot file so that I have this stile ready at hand every time I need it. That is much better.
The Normal.dotm is found here: C:Usersuser nameAppDataRoamingMicrosoftTemplates
So I start editing Normal.dotm and find out that the style Code is already there. Huh?
I created a new style in this document, and I hope I don’t need to do it again. Here below is the little test program for exporting the sound file from an ole bin file.
To run this program, you need to install both olefile and oletools. Use the regular installation program for python modules.
import olefile ≻import oletools.oleobj as oleobj ≻import io ≻import string ≻ ≻ole = olefile.OleFileIO("C:UsersjensOneDriveDocuments2020-05-16-sound-blog.docx.uncwordembeddingsoleObject1.bin") ≻for direntry in ole.listdir(): ≻ name = ''.join( ≻ filter(lambda x: x in string.printable, '_'.join(direntry)) ≻ ) ≻ print(name) ≻ if (name == 'Ole10Native'): ≻ stream = ole.openstream(direntry).read() ≻ ole_native = oleobj.OleNativeStream(stream) ≻ print(ole_native.filename) ≻ with open("C:UsersjensOneDriveDocuments2020-05-16-sound-blog.docx.uncwordembeddings" + ole_native.filename, 'wb') as f: ≻ f.write(bytes(ole_native.data)) ≻ ≻ole.close()
Friday 21 May
This day is a new day with new possibilities. Today it has been storming a lot. The sheep nets arrived today! We worked from our old home, and now it is Friday evening, and I thought I would bring this programming project a little further. That would be nice.
I was delighted with the result of my experiments on extracting the sound file from within an ole wrapper file. I had thought that would require days to do.
A couple of questions needs to be formulated and answered before I continue with this project:
- How will I name the sound files extracted from the OLE bin files? They need to be unique within the file.
- How should I markup the HTML of the sound file?
- Is there any conversion necessary?
- How will I support the media in the database?
I think that the export is possible. Yes, I can port my test program into the WordToHtml conversion program. Point 1 is no problematic issue, I can prepend the sound file with the name of the file, and then I can add the r: id number, and that is it. When doing it like so, I can have the sound files of all blog posts in the same directory. That is convenient.
Question 3 and 4 come later. Now it is time for question 2.
Saturday 22 May
I just signed up to get my jab. I am delighted!
Tonight I am looking into point two of my to-do list.
For this, I found a webpage I tried out: https://www.thesitewizard.com/html-tutorial/play-audio-music-with-html5.shtml
When I open the web page, it looks like this:
That is so simple, and it is almost ridiculous how easy it is.
https://www.codemag.com/article/1605051/Taming-the-HTML5-Audio-Control
I continued reading about the audio control, and it is said it is not working very well on mobile platforms. I have no idea about that yet.
I could post my test page to my webserver and look at how it renders my mobile phone. Let’s try that!
Sure enough, it works there as well. As a result of this test, I am ready to build support in my WordToHtml conversion program.
It is better to create a new test document with just the bare minimum.
Easy!
Monday 24 May
It is Monday. I got a little time over to work on the new sound feature of my blog system. Tonight I did the research only.
Tuesday 25 May
Tonight I got around to the programming. Here is the first attempt at detecting the OLEObject from document.xml. If you want to see how I built this program, you can read earlier blog posts about it. The last time I wrote about the blog system was on 26 February 2020, which is over a year ago.
If you click the screenshot, you see how I am looping over the run element in the document. When I found the object, I continue the loop until I get to the OLEObject element, and there I get hold of the rid. I hovered over the rId variable in the screenshot, and it displayed the value ‘rId5’.
With that, I can now try to get hold of the data of rId5 and write it to disk somehow. Here is the “final” result!
I decided to extract the number of the ID to be used in the filename, and that way, the sound files are unique, given that strBaseName is unique currently the user’s responsibility. The basename is the name of the word document, and I usually decide to give it the name of the date, and I don’t blog more than one blog post per day. You had to fix this on a commercial system somehow. This system is made for me, and I am OK with this.
Here is the above image as text.
for run_Item in list(current_Run.element): ≻ if run_Item.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}object": ≻ for object_Item in list(run_Item): ≻ if (object_Item.tag == "{urn:schemas-microsoft-com:office:office}OLEObject"): ≻ rId = object_Item.attrib['{http://schemas.openxmlformats.org/officeDocument/2006/relationships}id'] ≻ oleObject_Rel = doc_DocX.part.rels[rId] ≻ ole = olefile.OleFileIO(oleObject_Rel.target_part.blob) ≻ strOleUniqueFileNameWithExtension = None ≻ for direntry in ole.listdir(): ≻ name = ''.join( ≻ filter(lambda x: x in string.printable, '_'.join(direntry)) ≻ ) ≻ print(name) ≻ if (name == 'Ole10Native'): ≻ stream = ole.openstream(direntry).read() ≻ ole_native = oleobj.OleNativeStream(stream) ≻ print(ole_native.filename) ≻ strIdNumber = rId.replace('rId', '') ≻ strOleFileName, strOleFileExtension = os.path.splitext(ole_native.filename) ≻ strOleUniqueFileNameWithExtension = strOleFileName + strIdNumber + strOleFileExtension ≻ with open(strBaseDir + "" + strBaseName + "" + strOleUniqueFileNameWithExtension, 'wb') as f: ≻ f.write(bytes(ole_native.data)) ≻ ole.close() ≻ if (strOleUniqueFileNameWithExtension != None): ≻ strMarkup += "≺audio src="/media/{0}" controls≻≺/audio≻".format(strOleUniqueFileNameWithExtension)
This addition to my blog system is exciting for me. Now I can try this!
I was born 1967 in Stockholm, Sweden. I grew up in the small village Vågdalen in north Sweden. 1989 I moved to Umeå to study Computer Science at University of Umeå. 1995 I moved to the Netherlands where I live in Almere not far from Amsterdam.
Here on this site I let you see my creations.
I create, that is my hobby.