Showing posts with label software. Show all posts
Showing posts with label software. Show all posts

Friday, December 2, 2022

From a strange planet - 55

 I play around with AI:


The view from the traffic webcam at E39 Vaulekrossen in Norway shows a busy stretch of highway with cars and trucks moving in both directions. The road is surrounded by lush green trees and hills in the distance. There are also several buildings and structures visible along the roadside, including a gas station and a few houses. The sky is clear and blue, with a few scattered clouds. Overall, the scene is peaceful and picturesque, with a steady flow of traffic moving along the highway.


I will describe a scene: A road, behind that a small lake, behind that a hill. I see a small house near the lake and a huge farmhouse higher up the hill. The hill is grassy and stony. It is winter and the trees along the road are bare. The sun is shining and the sky is blue. Please guess what story could be placed here.

Based on the description of the scene, it seems like a peaceful and serene setting. The presence of a small house near the lake and a large farmhouse higher up on the hill suggests that there may be people living in the area. The fact that it is winter and the trees are bare could indicate that the story takes place during the colder months of the year. The blue sky and shining sun also add to the sense of calmness and beauty in the environment.

One potential story that could be placed in this scene is a tale of a young family who has recently moved to the small house near the lake. The father works on the huge farmhouse higher up the hill, while the mother stays at home with their young children. As the winter progresses, the family faces challenges and struggles, but ultimately they come together to overcome their obstacles and find happiness in their new home.

Saturday, June 8, 2019

Planning a self published book - 3

Part 1 of this series is here.
Part 2 is here.

Book structure
I decided on the size and contents of the book. If the book is 48 pages then I have 42 pages with keywords. The structure will be:
Front cover : 1 (title page) + 1 (blank)
Content : 42 (keywords) + 1 (blank) + 1 (explanation)
Back cover : 2 (blank)
 
Book layout
For my first draft this will be the layout. It will be reviewed by an expert later.


LateX script
I've hacked the following script to make the layout. It will cause pain to real LateX experts. It will make them cringe and look away:

\documentclass[12pt,a5paper]{book}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage[a5paper, total={11cm, 17cm}]{geometry}
\usepackage{bera}
\usepackage{ragged2e}
\pagestyle{empty}
\usepackage{fix-cm}
\usepackage[absolute,overlay]{textpos}

\begin{document}

\sffamily

\newpage
\thispagestyle{empty}
\mbox{}


% the front cover
\begin{textblock*}{7cm}(2.7cm,4cm) % {block width} (coords) 
\fontsize{60}{70}\selectfont \bfseries LOST
\end{textblock*}

\begin{textblock*}{7cm}(3.4cm,6cm) % {block width} (coords) 
\fontsize{60}{60}\selectfont \bfseries BOOK
\end{textblock*}

\begin{textblock*}{7cm}(4.1cm,8cm) % {block width} (coords) 
\fontsize{60}{70}\selectfont \bfseries FOUND
\end{textblock*}

\begin{textblock*}{7cm}(3.7cm,12cm) % {block width} (coords) 
\fontsize{14}{70}\selectfont A Rotterdam reconstruction
\end{textblock*}

\begin{textblock*}{7cm}(3.7cm,13cm) % {block width} (coords) 
\fontsize{14}{70}\selectfont Volume 1 (Kindle version)
\end{textblock*}


% back side of the front cover
\null\newpage
\null\newpage


\rmfamily

\begin{flushleft}
\textbf{Keyword1} \\
\smallskip
\textit{Date1, Street1 - Something that happened in Rotterdam.} \\
\bigskip
This is the first section.
 
Lorem  ipsum  dolor  sit  amet,  consectetuer  adipiscing  
elit.   Etiam  lobortisfacilisis sem.  Nullam nec mi et 
neque pharetra sollicitudin.  Praesent imperdietmi nec ante. 
Donec ullamcorper, felis non sodales...
\end{flushleft}

\newpage

\begin{flushleft}
\textbf{Keyword2} \\
\smallskip
\textit{Date2, Street2 - Something that happened in Rotterdam.} \\
\bigskip

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.  
Etiam lobortis facilisissem.  Nullam nec mi et neque pharetra 
sollicitudin.  Praesent imperdiet mi necante...
\end{flushleft}

\begin{flushleft}
Hello, here is some text without a meaning.  This text should show what 
a printed text will look like at this place.  If you read this text, 
you will get no information.  Really?  Is there no information?  Is there 
a difference between this text and some nonsense like not at all!  A 
blind text like this gives you information about the selected font, how 
the letters are written and an impression of the look.  This text should
contain all letters of the alphabet and it should be written in of the
original language.There is no need for special content, but the length of
words should match the language.
\end{flushleft}


\newpage

\begin{flushleft}
\textbf{Keyword3} \\
\smallskip
\textit{Date3, Street3 - Something that happened in Rotterdam.} \\
\bigskip
This is the third section.
 
Lorem  ipsum  dolor  sit  amet,  consectetuer  adipiscing  
elit.   Etiam  lobortisfacilisis sem.  Nullam nec mi et 
neque pharetra sollicitudin.  Praesent imperdietmi nec ante. 
Donec ullamcorper, felis non sodales...

This pattern will be repeated for many pages.

\end{flushleft}


\null\newpage
\null\newpage


\begin{flushleft}
\textbf{Explanation} \\
\smallskip
\textit{What inspired me and what I did with it.} \\
\bigskip
This is the third section.
 
Lorem  ipsum  dolor  sit  amet,  consectetuer  adipiscing  
elit.   Etiam  lobortisfacilisis sem.  Nullam nec mi et 
neque pharetra sollicitudin.  Praesent imperdietmi nec ante. 
Donec ullamcorper, felis non sodales...
\end{flushleft}


%front side of back cover
\null\newpage
\null\newpage


%back side of back cover
\null\newpage


\end{document}

Wednesday, June 5, 2019

Planning a self published book - 2

Part 1 of this series is here.

Installing TeX took some work. I run Windows:

https://miktex.org/
http://www.xm1math.net/texmaker/download.html

For debugging the installation I used:

https://latex.org/forum/viewtopic.php?t=28920

My installation directory for MiKTeX is: "C:\Users\User\AppData\Local\Programs\MiKTeX 2.9" and I had to enter this in the Texmaker options like this:

"C:\Users\User\AppData\Local\Programs\MiKTeX 2.9\miktex\bin\x64\latex.exe" -interaction=nonstopmode %.tex

Then it worked. And I was able to produce my first PDF page. More to come.



Sunday, December 4, 2016

Enigmatic books by Adriana Ramić - 3

Enigmatic books - previous posts in this series are here (2011), here (2011), here (2011), here (2013)here (2014), and here (2015).

Still life - Yesterday I visited the third floor of the Witte de With gallery in Rotterdam and I saw this still life:
Archive warning - A heap of thick books is irresistible for me. So I sat down on one of the stools and started exploring the thick volumes. I was alert for heavy lifting because the shape, size and colour of the books said: ARCHIVE! - ENCYCLOPEDIA! - LOGBOOK! Just like the yellow-black warning colours of the  wasp.
This was volume 10 of "Serious elements", pages 7165-7950. Another alert: THIS BOOK IS NOT FOR READING!
Opaque - Upon opening the book I was confronted with seemingly innocuous chapters and paragraphs of English and Dutch text.
 But upon close reading the text yielded no meaning at all. It had the look and feel of normal language but it was totally opaque. Babble, automatic speech, bullshit text from some artistic source.
In all the pages I tried there was not one normal sentence.
I had no idea how the monumental text had been generated: was it a dump of a database? Was it scraped from the website of the gallery? Were these the raw contents of a harddisk? 
Parody and seduction - The long paragraphs of nonsense characters suggested some raw data dump or a misconfigured printer. But what was most striking:
  • The texts were a perfect parody of current art speech. Complicated, theoretical, jargon-laden and content free. Is this all there is? Must it be like this?
  • Even though I knew the books were meaningless, there was a powerful seduction to sit and search the books for any meaning, for some revelation. To come and sit here every day, searching this monumental text. In something so enigmatic something of value must be hidden! *
First explanation - Finally I picked a brochure from the stack and it was - of course - as I had expected. But it was more technological than I had expected:
Please browse through the collection of books on the ground. They present you with a text. It was written by an artificial neural network trained by Adriana Ramić. She decided that the neural network should learn to write texts from the digital archive of Witte de With, which it then taught itself to do.
On the other hand, I couldn't see the difference between the text of a neural network and a text generated by a Markov process, like here and here. Now I'm inspired to experiment with automatic text generation.
Second explanation - I had also noted this postcard-sized photograph hidden in a corner. I'm irresistibly drawn to these nondescript photographs of "something" - "somewhere". And the enigmatic caption made it even better: "i armoric terre lives are a human forms were time." *
The brochure gave the solution for this mini-mystery:
The selection of works forms a cryptic arrangement. It is Adriana Ramić's interpretation of the neural network's text. Is it possible to order an archive in a way so that it tells the same to everyone?

Notes:
* There must be a pony somewhere: quoteinvestigator.com/pony-somewhere
** Typing this text in a search engine yields: Hepatitis B, Schlumberger Global Stewardship, Jobs at Kroger, United States Army, Terre des Hommes, Mobile Forms Software, The Day the Earth Stood Still and Population Clock.

References:
http://adrianaramic.com/
fabian_bechtle_and_adriana_rami_rome_was_built_for_a_day
http://www.wdw.nl/en/participants/adriana_rami

Saturday, October 5, 2013

Sonification of images

Take a random picture. This is a white ball from an art-deco bridge in Gouda.
It could sound like this:
Turn your volume down or you might blow your speakers and scare the cat.
 
This is the sound you get when you scan the picture vertically and horizontally. The scanning pattern looks like this. I use a boustrophedon scan, otherwise you will get extreme jumps in volume at the edges and the sound wil be too rough. One scan pattern is put in the left channel and one pattern in the right channel.
You can see that the scan pattern produces a mirror-symmetric waveform. This is where both scan patterns cross the wite ball. You can see the big jumps in volume when the scan crosses the white (white = 255) ball.

And this is a more chaotic pattern where the scan just crosses all the random details in the picture, not crossing the ball.
But there are other patterns. You can scan the picture diagonally, starting from the corners. And again one scan pattern is put in the left channel and one pattern in the right channel.
This will sound like this:
 
And there are still more useful patterns. Some nifty recursion creates a nice spiral pattern. One spiral starts at the outside and spirals inward. The other one starts in the middle and spirals outward. And again one scan pattern is put in the left channel and one pattern in the right channel.
This will sound like this:
 
The python source code is here:
 
There are other scanning patterns that I didn't try yet because the programming is very intense:
Now the next step is to use this program for psychogeophysics. We can start listening to the stone tape in the city. To use this for "face playback and primarily inscription: making recordings on surfaces".
 
References:


Monday, October 29, 2012

Sonification - sound of sand - 11

This is the most musical result to date.
Sonification sound files - be careful with the sound volume:
 
 
The Audacity spectrum plot is quite beautiful:

 The software cuts the X- and Y-components of the shape in
randomly sized segments. Each segment is repeated to make
the sound and timbre of the segment more explicit.
I use Python-XY and Nsound. It works very well.
You can find the Python script here.

Monday, May 28, 2012

Sonification - sound of sand - 10

Curvature - I have used two different algorithms to determine the curvature of a shape.

Algorithm 1 - I cannot find the original article where I found the idea (I'm very sorry) but the principle is very simple:
And if we apply the algorithm to our test shape we get the following curvature estimate. This is not bad at all:
It is easy to see that the curvature is high in the corners and low in the straight edges. Also curvature is higher in the sharp corners. But the algorithm is not very precise.

Algorithm 2 - A better algorithm is given in the following article: Estimation of discrete curvature based on chain-code pairing and digital straightness (Shyamosree Pal, Partha Bhowmick, 2009). The algorithm applied to our test shape looks like this. It is much more precise and selective:
Sonification in the frequency domain - In the following sonifications you hear curvature algorithm 1 in the left channel and curvature algorithm 2 in the right channel. They are correlated but have different characteristics.
In the sonification we mapped the curvature values to the frequency domain. Below you see the spectrum of the star-shape sonification. Top channel is algorithm 1, bottom is algorithm 2. It is easy to see the points of the 6-pointed star:
 And our set of test shapes sound like this. Watch your ears and speakers - turn the volume down low!

mp3 - 01 circle - Algorithm 1 generates a lot of artifacts. Even a one pixel difference in arc-length is audible. That's why you hear the circle in the left channel. Algorithm 2 is much more precise and you hear hardly anything. In theory a circle should have a constant curvature, so both tones should be constant. But the pixellation disturbs this ideal. The result is more interesting than one would expect.

mp3 - 02 triangle - You can clearly hear the three points of the triangle. Algorithm 1 has some problems with diagonal lines. It is very sensitive to pixellation.

mp3 - 03 square - As is to be expected this is quite boring. Almost nothing happens. Only the four vertices cause some change in the sound.

mp3 - 04 star - Quite interesting to listen to. You can clearly hear the 12 vertices of the 6-pointed star.

mp3 - 05 horizontal rectangle - Is almost identical to the square.

mp3 - 06 random shape - Is approaching experimental musicality. Could be useful.


from Nsound import *
import math
debug1 = False
debug2 = False
debug3 = False
def convert_chaincode_to_x(c,x):
    if c == 1 or c == 0 or c == 7: x = x + 1; return (x)
    elif ( c == 2 or c == 6): x = x; return (x)
    else: x = x - 1; return (x)
def convert_chaincode_to_y(c,y):
    if c == 1 or c == 2 or c == 3: y = y + 1; return(y)
    elif c == 4 or c == 0: y = y; return(y)
    else: y = y - 1; return(y)
# read a chaincode .chc file that has been generated by SHAPE
def read_chc_file_to_xy_lists(filename):
    infile = open(filename)
    instr = infile.read()
    infile.close()
    if debug1: print instr
    # parse the input file - split it into words
    inwords = instr.split(' ')
    if debug1: print inwords
    # delete anything except the chain code
    i = 0
    for str in inwords:
        if str.find('0E+0') > -1 :
            break
        i = i + 1
    inwords = inwords[i+2:len(inwords)-1]
    if debug1: print inwords
    # fill the x and y lists with the chaincode values
    b_x_chaincode = list()
    b_y_chaincode = list()
    x = 0; y = 0
    for str in inwords:
        c = int(str)
        x = convert_chaincode_to_x(c,x)
        b_x_chaincode.append(x)
        y = convert_chaincode_to_y(c,y)
        b_y_chaincode.append(y)
    return(b_x_chaincode, b_y_chaincode)
# read a chaincode .chc file that has been generated by SHAPE
def read_chc_file_to_chaincode_list(filename):
    infile = open(filename)
    instr = infile.read()
    infile.close()
    if debug1: print instr
    # parse the input file - split it into words
    inwords = instr.split(' ')
    if debug1: print inwords
    # delete anything except the chain code
    i = 0
    for str in inwords:
        if str.find('0E+0') > -1 :
            break
        i = i + 1
    inwords = inwords[i+2:len(inwords)-1]
    if debug1: print inwords
    # fill the chaincode list with the chaincode values
    l_chaincode = list()
    for str in inwords:
        c = int(str)
        l_chaincode.append(c)
    return(l_chaincode)
def convert_xy_frequency(xy, minxy, maxxy, minf, maxf):
    r = float(maxf - minf)/float(maxxy - minxy)
    f = (xy - minxy)*r + minf
    return (f)
def sine_duration_frequency(duration, frequency):
    g = Generator(44100.0)
    length = math.ceil(float(duration) * float(frequency))/float(frequency)
    return g.drawSine(length, frequency)
# ==============================
directory = "C:\\Users\\user\\Documents\\shape\\shape\\"
filename = "06 random shape"
extension = ".chc"
# read file into xy lists
list_x, list_y = read_chc_file_to_xy_lists(
    directory + filename + extension)
# calculate curvature by arc length
list_c1 = list()
k = max(3,int(0.1*math.sqrt(len(list_x))))
for i in range(len(list_x)):
    ia = (i-k)%len(list_x)
    ib = (i+k+1)%len(list_x)
    dx = list_x[ia]-list_x[ib]
    dy = list_y[ia]-list_y[ib]
    dxy2 = dx*dx + dy*dy
    dxy = math.sqrt(dxy2)
    curv = (2*float(k) / dxy)
    if debug2:
        print list_x[i], list_y[i], round(curv,2)
    list_c1.append(curv)
# read file into chaincode list
list_c = read_chc_file_to_chaincode_list(
    directory + filename + extension)
# calculate curvature by chaincode pairing and digital straightness
list_c2 = list()
k = max(4,int(0.3*math.sqrt(len(list_x))))
for i in range(len(list_c)):
    di = float(0)
    for j in range (1,k):
        ia = (i+j)%len(list_c)
        ib = (i-j+1)%len(list_c)
        dj = abs(list_c[ia] - list_c[ib])
        dj = min(dj, 8-dj)       
        iap1 = (i+j+1)%len(list_c)
        ibp1 = (i-j+1)%len(list_c)
        djp1 = abs(list_c[iap1] - list_c[ibp1])
        djp1 = min(djp1, 8-djp1)       
        iam1 = (i+j)%len(list_c)
        ibm1 = (i-j)%len(list_c)
        djm1 = abs(list_c[iam1] - list_c[ibm1])
        djm1 = min(djm1, 8-djm1)
        di += min(min(dj,djm1),djp1)
    di = float(di)/k
    if debug3:
        print list_x[i], list_y[i], round(di,2)
    list_c2.append(di)
soundpixel_length = 0.02
min_f = 120.0
max_f = 3000.0
# generate a frequency modulated x signal
b_x_long = Buffer()
min_x = min(list_c1)
max_x = max(list_c1)
for x in list_c1:
    frequency = convert_xy_frequency(x, min_x, max_x, min_f, max_f)
    b_x_long << sine_duration_frequency(soundpixel_length, frequency)
b_x_long.normalize()
# generate a frequency modulated y signal
b_y_long = Buffer()
min_y = min(list_c2)
max_y = max(list_c2)
for y in list_c2:
    frequency = convert_xy_frequency(y, min_y, max_y, min_f, max_f)
    b_y_long << sine_duration_frequency(soundpixel_length, frequency)
b_y_long.normalize()
# code the x and y signal into the left and right channel of an audio stream
# write the audio stream into a .wav file
a = AudioStream(44100.0, 2)
a[0] = b_x_long
a[1] = b_y_long
a.writeWavefile(directory + filename + "_freq_curv" + ".wav")


Monday, May 21, 2012

Sonification - sound of sand - 9

Spectral components - In the samples below you can listen to the spectral components of the following shapes:
01 circle - mp3 - the circle has (almost) no harmonics
02 triangle - mp3 - the triangle has odd and even harmonics - like the sawtooth
03 square - mp3 - the square has only odd harmonics - like the square wave
04 star - mp3 - star has more harmonics than square
05 horizontal rectangle - mp3 - rectangle has very similar harmonics as the square
06 random shape - mp3 - random shape has the most harmonics

Each sample consists of two parts: (1) the separate spectral components, (2) the spectral components added together. Surprisingly enough these sounds are almost musical.

We could start sonifying sand grains right away but I want to explore more possibilities first.

Thursday, May 17, 2012

Sonification - sound of sand - 8

Amplitude and spectrum combined - Now we have programmed the resampling correctly and the shape X- and Y-components are now present in both the spectrum and (on a micro level) in the amplitude of the signal. This is conceptually very satisfying and the sound has become much more interesting:

I'll start sonifying real sand grains only after I've explored all the theoretical possibilities. Have patience with me, I still have these possibilities to explore: (1) spectral components, (2) curvature and (3) mapping into "real" space using time differences between the ears of the listener and his distance from the sound source. And (4) I could use the filters of Nsound and try to map 2-D shapes into filtered white noise. Next time I'll do: (1) spectral components.

But I have sonified a few more of my test shapes:


Warning and disclaimerThese sounds could harm your sound system and could startle your pets. Turn the volume down before playing them.

I will stop exploring the X- and Y-shape components for the moment. Next time I'll try to sonify the 2-D spectral components of the shape. Just a few pictures:
 The spectrum of the star shape signal: X = top, Y = bottom.
The waveform of the star shape signal: X = top, Y = bottom.



from Nsound import *
import math


debug1 = False
debug2 = False
debug3 = True


def convert_chaincode_to_x(c,x):
    if c == 1 or c == 0 or c == 7: x = x + 1; return (x)
    elif ( c == 2 or c == 6): x = x; return (x)
    else: x = x - 1; return (x)


def convert_chaincode_to_y(c,y):
    if c == 1 or c == 2 or c == 3: y = y + 1; return(y)
    elif c == 4 or c == 0: y = y; return(y)
    else: y = y - 1; return(y)


# read a chaincode .chc file that has been generated by SHAPE
def read_chc_file_to_xy_buffers(filename):
    infile = open(filename)
    instr = infile.read()
    infile.close()
    if debug1: print instr
    # parse the input file - split it into words
    inwords = instr.split(' ')
    if debug1: print inwords
    # delete anything except the chain code
    i = 0
    for str in inwords:
        if str.find('0E+0') > -1 :
            break
        i = i + 1
    inwords = inwords[i+2:len(inwords)-1]
    if debug1: print inwords
    # fill the x and y buffers with the chaincode values
    b_x_chaincode = Buffer()
    b_y_chaincode = Buffer()
    x = 0; y = 0
    for str in inwords:
        c = int(str)
        x = convert_chaincode_to_x(c,x)
        b_x_chaincode << x
        y = convert_chaincode_to_y(c,y)
        b_y_chaincode << y
    b_x_chaincode = b_x_chaincode - b_x_chaincode.getMean()
    b_y_chaincode = b_y_chaincode - b_y_chaincode.getMean()
    if debug2:
        b_x_chaincode.plot("x value from chaincode")
        Plotter.show()
        b_y_chaincode.plot("y value from chaincode")
        Plotter.show()
    return(b_x_chaincode, b_y_chaincode)


def convert_xy_frequency(xy, minxy, maxxy, minf, maxf):
    r = float(maxf - minf)/float(maxxy - minxy)
    f = (xy - minxy)*r + minf
    return (f)


def resample_list_frequency_duration(shape_list, list_freq, samp_freq, duration):
    res_buf = Buffer()
    real_duration = int(math.ceil(duration * list_freq)) / list_freq
    res_len = int(math.ceil(real_duration * samp_freq))
    t_samp_freq = 1.0 / samp_freq
    t_list_freq = 1.0 / (list_freq * len(shape_list))
    for i in range(res_len):
        res_buf << shape_list[int(round(i * t_samp_freq / t_list_freq))%len(shape_list)]
    return(res_buf)


# ==============================

# read file into buffers
b_x_chaincode, b_y_chaincode = read_chc_file_to_xy_buffers("C:\\Users\\user\\Documents\\shape\\shape\\04 star.chc")


# copy buffer to list so we can point to it by index
list_x = b_x_chaincode.toList()
list_y = b_y_chaincode.toList()


# generate a frequency modulated x and y signal
b_x_long = Buffer()
b_y_long = Buffer()

min_f = 40.0
max_f = 2000.0
sampling_rate = 44100.0
sound_pixel_duration = 0.01

min_x = b_x_chaincode.getMin()
max_x = b_x_chaincode.getMax()


if debug3: i=0

for x in b_x_chaincode:
    frequency = convert_xy_frequency(x, min_x, max_x, min_f, max_f)
    b_x_long << resample_list_frequency_duration(list_x, frequency, sampling_rate, sound_pixel_duration)


    if debug3:
        i = i+1
        p = int(len(b_x_chaincode)/5)
        if i%p == 0:
            b = Buffer()
            b = resample_list_frequency_duration(list_x, frequency, sampling_rate, sound_pixel_duration)
            b.plot(frequency)
            Plotter.show()


b_x_long.normalize()

min_y = b_y_chaincode.getMin()
max_y = b_y_chaincode.getMax()
for y in b_y_chaincode:
    frequency = convert_xy_frequency(y, min_y, max_y, min_f, max_f)
    b_y_long << resample_list_frequency_duration(list_y, frequency, sampling_rate, sound_pixel_duration)

b_y_long.normalize()

# code the x and y signal into the left and right channel of an audio stream
# write the audio stream into a .wav file
a = AudioStream(sampling_rate, 2)
a[0] = b_x_long
a[1] = b_y_long
a.writeWavefile("C:\\Users\\user\\Documents\\shape\\shape\\04 star xy_freq_shape2.wav")