Jump to content
View in the app

A better way to browse. Learn more.

Tinkerunity

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Measuring how hard you (and your partner) snore at night..

Featured Replies

Geschrieben

Required:

* two Sound Intensity bricklets, dangling some 50cm above where your heads are normally positioned in bed.

* [optional] Wifi module to pipe the collected data to your PC in another room

* some trivial software (below) continuously sampling the stereo bricklets, and dumping the measured values to files.

 

I chose to dump the samples as 32-bit floats so that I can import the "nightly dumps" into Audacity using its "File > Import > Raw Data" feature.

 

My setup produces 2 raw files, one for the "left" and "right" bed positions. Audacity quickly proves that my girlfriend was right in claiming I snore quite loudly.  :-[

 

package com.softwarepearls.apps.hardware.tinkerforge.health.snoring;

import static com.softwarepearls.lego.time.TimeAndDateKit.*;

import com.softwarepearls.lego.audio.enums.StereoPosition;
import com.softwarepearls.lego.filesystem.files.FileKit;
import com.softwarepearls.lego.hardware.tinkerforge.enums.BrickletType;
import com.softwarepearls.lego.hardware.tinkerforge.interfaces.input.SoundIntensity;
import com.softwarepearls.lego.hardware.tinkerforge.stack.BrickletDescriptor;
import com.softwarepearls.lego.hardware.tinkerforge.stack.TinkerForgeStack;
import com.softwarepearls.lego.java.system.SystemProperties;
import com.softwarepearls.lego.time.Frequency;
import com.softwarepearls.lego.time.TimeAndDateKit;
import com.tinkerforge.TinkerforgeException;

import java.io.*;
import java.util.Arrays;
import java.util.List;

/**
* Bare-bones two-person "sleep noise" recorder (meant to record snoring). For
* every night, produces two mono sound files holding the noise volume (not true
* sound!) recorded between 20:00 and 09:00.
* <P>
* Find out who snores the loudest, and when (apnea diagnoser?).
*/
public final class SleepRecorder implements Runnable {

private static final int RECORD_START_HOUR = 20;
private static final int RECORD_STOP_HOUR = 9;

private final static Frequency SAMPLING_FREQUENCY = Frequency.EVERY_10_MS;

// the following constants are specific to my personal setup. Modify to suit
// yours.
private final static String STACK_IP_ADDRESS = "192.168.0.114";
private final static String DUMP_FOLDER = "Documents/Audacity/SleepRecordings";

private final static String RIGHT_SENSOR_UID = "mkt";
private final static String LEFT_SENSOR_UID = "mmV";

private static final List<BrickletDescriptor> EXPECTED_BRICKLETS = Arrays.asList(

//
		new BrickletDescriptor(BrickletType.BRICKLET_SOUND_INTENSITY, "mkt"),//
		new BrickletDescriptor(BrickletType.BRICKLET_SOUND_INTENSITY, "mmV")//
		);

private DataOutputStream rightOut;
private DataOutputStream leftOut;

private void go() throws TinkerforgeException, IOException {

	Runtime.getRuntime().addShutdownHook(new Thread(this));

	final TinkerForgeStack tinkerForgeStack = TinkerForgeStack.initializeTinkerForgeStack(EXPECTED_BRICKLETS, STACK_IP_ADDRESS);
	final SoundIntensity rightSoundIntensity = (SoundIntensity) tinkerForgeStack.getBricklet(RIGHT_SENSOR_UID);
	final SoundIntensity leftSoundIntensity = (SoundIntensity) tinkerForgeStack.getBricklet(LEFT_SENSOR_UID);

	boolean recording = false;
	while (true) {
		if (recording) {
			recordSounds(rightSoundIntensity, leftSoundIntensity);

			recording = !waitForEnd();

			if (!recording) {
				closeFiles();
			}
			SAMPLING_FREQUENCY.delay();

		} else {

			recording = waitForStart();
			if (recording) {
				initFiles();
				continue;
			}
			Frequency.EVERY_10_SECOND.delay();
		}
	}
}

private void recordSounds(final SoundIntensity rightSoundIntensity, final SoundIntensity leftSoundIntensity) throws TinkerforgeException, IOException {

	final int rightIntensity = rightSoundIntensity.getIntensity();
	final int leftIntensity = leftSoundIntensity.getIntensity();
	writeToAudioFile(rightIntensity, StereoPosition.RIGHT);
	writeToAudioFile(leftIntensity, StereoPosition.LEFT);
}

private void initFiles() throws IOException {

	System.out.println("Initializing recordings for today " + currentDayOfMonth() + " " + currentMonth());

	rightOut = initRecordingFile(StereoPosition.RIGHT);
	leftOut = initRecordingFile(StereoPosition.LEFT);
}

private void closeFiles() throws IOException {

	System.out.println("Closing recordings.");

	rightOut.close();
	leftOut.close();
	rightOut = leftOut = null;
}

private DataOutputStream initRecordingFile(final StereoPosition stereoPosition) throws IOException {

	final File userHome = new File(SystemProperties.getUserHome());
	final File dumpRootDirectory = new File(userHome, DUMP_FOLDER);
	final File yearDirectory = new File(dumpRootDirectory, "" + currentYear());
	final String monthDirName = String.format("%02d_%s", currentMonthNumber() + 1, currentMonth());
	final File monthDirectory = new File(yearDirectory, monthDirName);
	FileKit.ensurePathExists(monthDirectory.getAbsolutePath());

	final String filename = String.format("%02d_%s_%s.raw", currentDayOfMonth(), currentDayName().substring(0, 3), stereoPosition);
	final File noiseFile = new File(monthDirectory, filename);
	System.out.println("Opened OK: " + noiseFile);
	final FileOutputStream fos = new FileOutputStream(noiseFile);
	final BufferedOutputStream bos = new BufferedOutputStream(fos);
	final DataOutputStream dos = new DataOutputStream(bos);

	return dos;
}

private void writeToAudioFile(final int intensity, final StereoPosition position) throws IOException {

	DataOutputStream out = rightOut;
	if (position == StereoPosition.LEFT) {
		out = leftOut;
	}
	final float floatIntensity = ((float) intensity) / 4096;
	out.writeFloat(floatIntensity);
}

private boolean waitForStart() {

	// return true;
	return TimeAndDateKit.currentHour() == RECORD_START_HOUR;
}

private boolean waitForEnd() {

	return TimeAndDateKit.currentHour() == RECORD_STOP_HOUR;
}

public static void main(final String[] args) throws TinkerforgeException, IOException {

	new SleepRecorder().go();
}

@Override
public void run() {

	try {
		closeFiles();
	}
	catch (final IOException e) {
		e.printStackTrace();
	}
}
}

Geschrieben
  • Autor

Now my girlfriend thinks she may be sensitive to electromagnetic radiation, so in the interest of domestic peace, I removed my (Wifi-based) setup  :'(

 

So now I need an EM radiation sensor.. hmmm... where could I find one of those?  ::)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.