Multiple changes & new post
authorMax Value <greenwoodw50@gmail.com>
Mon, 16 Dec 2024 12:37:43 +0000 (12:37 +0000)
committerMax Value <greenwoodw50@gmail.com>
Mon, 16 Dec 2024 12:37:43 +0000 (12:37 +0000)
- Added Bayeux tapestry post
- Added media directory
- Added media serving from the server
- RWD changes to stylesheet

index.py
media/bayeux/bayeux1.png [new file with mode: 0644]
media/bayeux/bayeux2.png [new file with mode: 0644]
media/bayeux/bayeux3.png [new file with mode: 0644]
pages/bayeux.md [new file with mode: 0644]
static/style.css
templates/page.html

index abc7c2917df4579cbbdb74e82971bee64ef39619..8625e37696c4b5ec81da1c9b6f91bf5c710700f2 100755 (executable)
--- a/index.py
+++ b/index.py
@@ -1,6 +1,6 @@
 #! .venv/bin/python3
 
-from flask import Flask, Response, request, render_template, redirect
+from flask import Flask, Response, request, render_template, redirect, send_from_directory
 import markdown
 from os import listdir
 from markdown.extensions.toc import TocExtension
@@ -171,5 +171,9 @@ def generate_page(title):
                page = Page(title = "404", abstract = "Page not found!")
                return page.make()
 
+@app.route("/<string:title>/<string:filename>")
+def get_media(title, filename):
+       return send_from_directory(f"./media/{title}", filename)
+
 if __name__ == "__main__":
-       app.run(host='127.0.0.1', port=5000)
+       app.run(host='127.0.0.1', port=5000, debug=True)
diff --git a/media/bayeux/bayeux1.png b/media/bayeux/bayeux1.png
new file mode 100644 (file)
index 0000000..64898fc
Binary files /dev/null and b/media/bayeux/bayeux1.png differ
diff --git a/media/bayeux/bayeux2.png b/media/bayeux/bayeux2.png
new file mode 100644 (file)
index 0000000..77f0e93
Binary files /dev/null and b/media/bayeux/bayeux2.png differ
diff --git a/media/bayeux/bayeux3.png b/media/bayeux/bayeux3.png
new file mode 100644 (file)
index 0000000..2bf63fe
Binary files /dev/null and b/media/bayeux/bayeux3.png differ
diff --git a/pages/bayeux.md b/pages/bayeux.md
new file mode 100644 (file)
index 0000000..dc33bcf
--- /dev/null
@@ -0,0 +1,73 @@
+title: An Audio Bayeux Tapestry
+abstract: With the power of technology, the Bayeux tapestry is now avaiable for the blind.
+keywords: programming,audio
+date: 16/12/2024
+
+# An Audio Bayeux Tapestry
+
+Hello!
+
+With the power of technology, the Bayeux tapestry is now avaiable for the blind.
+
+<!-- <audio src="blog.ozva.co.uk/static/bayeux.wav" controls /> -->
+
+In this post I'll show you how this was achived.
+
+## The image
+
+![image](/bayeux/bayeux1.png "Before ajustment")
+
+The scan available online[^1] is not centered, unless we want an unclear or ragged edge on our audio, we must first straighten and strectch the tapestry flat.
+
+I did this with a simple python script.
+
+```
+for (i, pixel) in enumerate(line):
+            value = np.mean(pixel) # Get the brightness
+            if value < THRESHHOLD:
+                front_index = i # Set the index of our in-point
+                break
+```
+
+As you can see, by scrolling our way across each line and noting where the pixel value is greater than our threshold (set at 225), we can figure out the bounds of that particular line of the tapestry.
+
+```
+trim_line = np.array([line[front_index:back_index]], dtype=np.uint8)
+new_image.append(cv.resize(trim_line, (image_width, 1))[0])
+```
+
+We then stretch the line to the total width of the image.
+
+This produces a far more regular image.
+
+![image](/bayeux/bayeux2.png "After ajustment")
+
+This is very stretched, but this is no problem. Since it will end up as a spectrogram whose dimentions we don't care much for we will skip the step of fixing this.
+
+## The spectrogram
+
+The image can then be turned into a spectrogram with the power of the FFT.
+
+```
+data = np.fft.irfft(image, h*2, axis=1).reshape((w*h*2)) # Reshape and get the FFT output
+data -= np.average(data) # Remove DC offset
+data *= (2**15-1.)/np.amax(data) # Normalize
+```
+
+As a side effect of the jump from one side of the image to the other, there is a sample impulse every 1,500 samples, we record this high point and subtract it from all following samples.
+
+```
+high_point = data[1500]
+for i in range(0, len(data), 1500):
+       data[i] -= high_point
+```
+
+If we split the image in half and process seperately, we can then combine them over the right and left audio channels to get a more resolute image.
+
+This solves another issue:
+
+Say you have an image which is not so rectangular and is intended to have a "silent" background. As this image rises to the top of the frame, hovering around 20,000kHz it can become quite unplesant. Splitting the sound across right and left not only produces some sence of space, but also gives you a wholy wider and more plesent range of frequencies.
+
+![image](/bayeux/bayeux3.png "Finished spectrogram")
+
+[^1]: Link: <a href="https://en.wikipedia.org/wiki/File:Tapisserie_de_Bayeux_31109.jpg">https://en.wikipedia.org/wiki/File:Tapisserie_de_Bayeux_31109.jpg</a>
index 0220febb61a0f8f393620283aa58bdef52b277b5..a5e9b4b1680ebf0b1a19b12391c34a78f29d29c9 100644 (file)
@@ -17,25 +17,43 @@ body {
     font-size: 2.8em;
 }
 
-nav {
-    position: absolute;
-    top: 0;
-    bottom: 0;
-    left: 0;
-    right: 80%;
-    padding: 10px;
-    overflow: scroll;
-    border-right: 2px solid var(--primary);
+@media (max-width: 700px) {
+    #extra {
+    display: none;
+    }
+    nav {
+        padding: 10px;
+        border-bottom: 2px solid var(--primary);
+    }
+    main {
+        padding: 10px;
+    }
 }
 
-main {
-    position: absolute;
-    top: 0;
-    bottom: 0;
-    left: 20%;
-    right: 0;
-    padding: 10px;
-    overflow: scroll;
+@media (min-width: 700px) {
+    nav {
+        position: absolute;
+        top: 0;
+        bottom: 0;
+        left: 0;
+        right: 75%;
+        padding: 10px;
+        overflow: scroll;
+        border-right: 2px solid var(--primary);
+    }
+    main {
+        position: absolute;
+        top: 0;
+        bottom: 0;
+        left: 25%;
+        right: 0;
+        padding: 10px;
+        overflow: scroll;
+    }
+}
+
+main > *:not(hr) {
+    width: min(100%, 700px);
 }
 
 a:link {
@@ -57,6 +75,10 @@ hr {
     border: 1px solid var(--primary);
 }
 
+img {
+    width: min(80%, 500px);
+}
+
 @media (prefers-color-scheme: dark) {
     :root {
         --primary: white;
index 5aebe1228ac06799af54017e58f3f5d451dd58af..185bab7928b629fc5b58b633552a7584a988bd78 100644 (file)
                                <button type="submit">Search</button>
                        </form>
                        </search>-->
-                       <hr>
-                       <ul>
-                               <li>
-                                       These are some recent posts!
-                               </li>
-                       </ul>
+                       <div id="extra">
+                               <hr>
+                               <ul>
+                                       <li>
+                                               These are some recent posts!
+                                       </li>
+                               </ul>
+                       </div>
                </nav><main>
                        <h1 class='mainTitle'>{{title}}</h1>
                        {% if date %}