About

A fart machine is a device that randomly emits a farting sound from time to time.

In order to recreate this device using Node-Red, a pool of fart sounds is added somewhere accessible to Node-Red and then a flow is constructed to perform the following operations, in order:

  • randomly wait an amount of time,
  • read the files in a directory,
  • randomly select a file,
  • play the file out of the sound-card

Hardware Preparations

Note that most node-red contributions related to playing sounds are directed at doing so within the browser and not out of the soundcard. If node-red is running under Docker, the soundcard must be passed through to the container by using the –device command-line option:

  --device=/dev/snd:/dev/snd 

Passing the snd directory from /dev should pass through all the devices necessary to be able to play sound out of the sound card.

amixer or alsa-mixer must be used in order to unmute and set the volume of the sound-card.

Sounds

Fart sounds are publicly available on the Internet and can be downloaded and stored within a directory that node-red can then access and play. Preferably, the sounds should be in wav format, due to the easy compatibility with tools accessed by node-red or by node-red directly. Another idea is to browse repositories for sound-effects from large companies such as Warner Brothers, etc, that might provide a larger palette of possible sounds.

Flow

Here is a rundown of the fart-machine:

  • the first node uses the JavaScript setTimerEvent to randomly (re)install a timer as a countdown to when a farting sound must be emitted,
  • FS List is part of a filesystem operations module that is capable of listing files within a directory and has to be installed via the node-red palette by looking up node-red-contrib-filesystem, this node is used to read the directory of farting sounds,
  • the next node will randomly select a sound file from the previous FS List node and then join it with the full path,
  • the built-in read file node will read the binary wav file,
  • the sox node uses the play command from the sox package to play the file and the node itself can be installed in node-red using the palette manager by looking up node-red-contrib-sox-utils

Code

[{"id":"ee702606c0ef1b99","type":"tab","label":"Fart Machine","disabled":false,"info":"","env":[]},{"id":"e061d8c99f26b33d","type":"sox-play","z":"ee702606c0ef1b99","name":"","outputDevice":"default","manualOutput":"","gain":"0","startNew":"skip","playStream":false,"inputEncoding":"signed-integer","inputChannels":1,"inputRate":16000,"inputBits":16,"debugOutput":false,"x":820,"y":240,"wires":[["93be5207bd8c23fd"]]},{"id":"93be5207bd8c23fd","type":"debug","z":"ee702606c0ef1b99","name":"debug 93","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":240,"wires":[]},{"id":"050eabe2c526d8a3","type":"file in","z":"ee702606c0ef1b99","name":"","filename":"payload","filenameType":"msg","format":"","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":660,"y":240,"wires":[["e061d8c99f26b33d"]]},{"id":"58e55b00514d3e70","type":"inject","z":"ee702606c0ef1b99","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":140,"wires":[["0110cf25e6509e38"]]},{"id":"0110cf25e6509e38","type":"fs-list","z":"ee702606c0ef1b99","name":"","path":"/projects/audio/publicannounce/soundboard/farts","pathType":"str","pattern":"*","patternType":"str","filter":"files","recursive":false,"follow":true,"property":"payload","propertyType":"msg","x":320,"y":240,"wires":[["91c6480ba174e091"]]},{"id":"91c6480ba174e091","type":"function","z":"ee702606c0ef1b99","name":"random file","func":"msg.payload = `/projects/audio/publicannounce/soundboard/farts/${msg.payload[Math.floor(Math.random()*msg.payload.length)]}`\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":240,"wires":[["050eabe2c526d8a3"]]},{"id":"dd0f89a6927eacfa","type":"function","z":"ee702606c0ef1b99","name":"random timer","func":"","outputs":1,"timeout":0,"noerr":0,"initialize":"function myFunction() {\n    var min = 5,\n        max = 30;\n    var rand = Math.floor(Math.random() * (max - min + 1) + min)\n    msg = {}\n    msg.payload = \"now\"\n    node.send([ msg ])\n    var randomTimer = setTimeout(myFunction, rand * 1000)\n    flow.set('timerHandle', randomTimer)\n}\n\nmyFunction()\n\n\n","finalize":"var timerHandle = flow.get('timerHandle')\nclearTimeout(timerHandle)","libs":[],"x":150,"y":240,"wires":[["0110cf25e6509e38"]]}]

Combining with Other Projects

Farting is cool, but some other applications could be created to use this jukebox system. For example, the sensor cocktail project can be used to play sounds once a certain sensor threshold is reached, for example, given the luminosity, one could make the jukebox say "good morning" or "good night". This does not take much and all that is needed is to pass the sensor data into the flow and branch on the different values.

For example, the flow illustrated in the image below will play a "gay!" sound effect whenever the ambient noise from the sensor cocktail project exceeds 70 decibels.

the flow is just the same as the fart machine, just that the noise level is fed into the flow via the "link in" node (left) and then a "switch" node branches on the decibels, with the top branch exceeding 70dB and the bottom branch leading to emp (or a debug node).

With this setup, you can automatically make the fart machine say "gay!" whenever the noise threshold in the street exceeds legal limit, such as for people racing cars within residential areas, that make noise way, way above the legal limit.


fuss/node-red/flows/fart_machine.txt · Last modified: 2025/02/03 08:06 by office

Wizardry and Steamworks

© 2025 Wizardry and Steamworks

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.