Audio - looping recorder needed [FILLED]

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#31 Post by greengeek »

Thanks mike - i will have a play with this and see what features I can pilfer. cheers

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#32 Post by Ibidem »

FYI:

Code: Select all

AVAILABLE=`df $STORAGEDIR |tail -n 1|awk '{ print $4 }'`
Deleting the oldest file when you have no space is not necessarily enough, since compression means that size is variable (you might delete a file that compressed well but write one that doesn't).

The comment about "while true" needing to sleep so the CPU doesn't overload is only true for CPU-bound stuff; recording is usually I/O-bound (the speed of audio input slows it down enough).

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#33 Post by greengeek »

Ibidem wrote:

Code: Select all

AVAILABLE=`df $STORAGEDIR |tail -n 1|awk '{ print $4 }'`
Thanks, that produces a nice tidy number. I have to think about how I can best use that information.

It would be nice to offer the user three possible methods of control:
1) Total file numbers (as I have done so far)
2) "Specified storage" - where the user can set a total of say, 2GB as the maximum storage limit for the record directory.
3) "Overfill avoidance" - where I could use your suggested syntax to keep track of when the remaining partition space got down to say 200MB, then remove old files to increase that remaining storage.

As far as I can tell the syntax above is calculating remaining partition space - as I assume the remainder of the partition is currently available for that directory to grow into. Have i understood that correctly?

Is it possible to create a directory that is 'size limited'? I would not be keen to allow an entire partition to be used up by the storage directory, but if I could limit that directory to a specific size then I can use your syntax to calculate the "loop point".

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#34 Post by greengeek »

With regard to limiting a directory to a specific size, it seems more complex than I would have expected. One quote here:

Quota is based upon filesystems, but you can always create a virtual filesystem and mount it on a specific (empty) directory with the usrquota and/or grpquota flags.

In steps this will be:

create the mount point
create a file full of /dev/zero, large enough to the maximum size you want to reserve for the virtual filesystem
format this file with an ext3 filesystem (you can format a disk space even if it is not a block device, but double check the syntax of every - dangerous - formatting command)
mount the newly formatted disk space in the directory you've created as mount point, e.g. Code: mount -o loop,rw,usrquota,grpquota /path/to/the/formatted/disk/space /path/of/mount/point
Set proper permissions
Set quotas and the trick is done.
Hoping there's a better way...

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#35 Post by greengeek »

Aah! I get it! If I change $4 to $3 I get the "used" figure, rather than the "remaining" figure:

Code: Select all

# df /root/record32
Filesystem     1K-blocks  Used Available Use% Mounted on
unionfs          6445968 21068   6424900   1% /
# df /root/record32 |tail -n 1|awk '{ print $4 }'
6424900
# df /root/record32 |tail -n 1|awk '{ print $3 }'
21068
#

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#36 Post by greengeek »

I changed the script to include Ibidems space calculation and it works, but I dont understand why the 'used' figure coming back from df ("30164") is so different from the figure I get if I rightclick the record directory and look at properties (shows "8432k").

Doesnt affect the operation of the script, but does affect the understanding of the user in terms of calculating what they want to set as maxima.

User avatar
mikeb
Posts: 11297
Joined: Thu 23 Nov 2006, 13:56

#37 Post by mikeb »

hmm discrepancies.... might be affected if symlinks are counted as files.... or file system block size related...both theories seem unlikely.

The mysteries of linux eh :)


mike

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#38 Post by greengeek »

Hang on - i'm not thinking clearly:
'df' is concerned with the filesystem - so that is what I can use if i am calculating the effect of the recording on the partition, whereas 'du' will give me the actual storage space in use in the directory

Code: Select all

# df /root/record32
Filesystem     1K-blocks  Used Available Use% Mounted on
unionfs          6445968 18588   6427380   1% /
# du /root/record32
60	/root/record32
So filecount and/or du value can be used by the user to specify their preferred limits, while df value can be used as a backstop protection for the partition space.

EDIT : I've tried a modified version of Ibidems awk and came up with the number of kB in use in the directory:

Code: Select all

# du /root/record32 |tail -n 1|awk '{ print $1 }' 
60
Very happy. thanks for the syntax Ibidem.
Attachments
Directory_properties.jpg
(23.01 KiB) Downloaded 187 times

User avatar
mikeb
Posts: 11297
Joined: Thu 23 Nov 2006, 13:56

#39 Post by mikeb »

input overload eh :)


similarly
df /root/record32 | tail -n 1 |awk '{ print $4 }'

for yer free space.

fixed bitrate will produce sizes dependant only on time not content.

mike

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#40 Post by greengeek »

I've tidied up the script a bit and removed some redundant repetition, and added some colour to the gxmessages for clarity. I'm still using the 'number of files' as my calculation in this version, but hope to add an optional 'directory size' check in later version.

I have also added a filetype check so that the delete phase only removes .mp3 format files. That way i can copy the script to an empty usb stick, set the path parameter in the script to that usb drive and have it run as a selfcontained security recorder that you unmount when you want to take the recordings away. Nothing to install on the actual system:

I also hope to give it a good gui one day but that is well beyond me at present.

Other than that I think this is pretty close to a final basic version that does what I set out to do without too much complexity:

Code: Select all

#!/bin/bash
#mictrapper_0.4

	#"mictrapper" is a script to allow you to record a series of audio files captured from your microphone and to automatically delete the oldest file when the storage directory reaches the limit you define (determined by the max number of files you have chosen as needed to cover the desired timeframe). After deleting the oldest file it continues recording the newest one.
	#Credit to all contributors in this thread:
	#http://murga-linux.com/puppy/viewtopic.php?t=96290
	#NOTE - before using this program please check that your microphone is working correctly and is selected in your mixer. Set the volumes manually. This script does not have control over those factors.
	#You can modify the storage directory, audio record length, mp3 bitrate and maximum number of files to be kept. The total period of time covered by your stored recordings is determined by the audio recording length multiplied by what you select as the max number of stored files. For example, if you set RECORDINGLENGTH=180 seconds (3 minutes) and MAXFILES=480 then your storage directory will be keeping the last 24 hours of recordings.

 #Define the length of each recorded segment in seconds:
 #I recommend starting with a low number for testing purposes:
RECORDINGLENGTH=8

 #Define max number of files necessary to capture the required timeframe but not exceed available storage area. (If using 3 minute files  we need 480 files per 24 hours):
 #I recommend starting with a low maxfiles number for testing purposes:
MAXFILES=3
  #NOTE: I do not recommend using a value of MAXFILES=1. Best to use 2 or above to avoid overwriting previous audio too soon.

 #Define the bitrate of the final mp3 encoding. 
 #"32" gives small file size yet generally acceptable quality.
 #"64" can give better audio if you have a good microphone.
 #"128" or higher just seems a bit too fancy for my needs...
 #Higher settings create large file sizes.
MP3BITRATE=32
 #If bitrate=32 + recordinglength=180 this gives an audio segment size of 704kB
 #which covers 3 minutes. Multiply that by 20 to get 1 hour = 14080kB. (= 14MB)
 #3mins @ bitrate=32  = 704kB
 #1 hour @ bitrate=32 = 14080kB = 14MB
 #1 day @ bitrate=32  = 337920kB = 340MB (these figures approximate only)
 #Make sure you choose a location (path) that has plenty of room - take care if you are using
 #a frugal installation with a savefile as a long recording time could easily fill it up.

 #OK, lets do this:
	while true; do

 #Define the directory being used to store the recordings:
path="/root/record$MP3BITRATE"

	#create the recording directory if it doesnt already exist. Exit on error if it exists but is not a directory:
	if [[ ! -e $path ]]; then
    mkdir $path
	elif [[ ! -d $path ]]; then
    echo "$path already exists but is not a directory" 1>&2
    gxmessage " 
   
       ... Path exists, but is not a directory. Exiting ...    " -center -buttons , -timeout 10 -name  "ERROR CONDITION" &
    exit
	fi
 
 #Define whether the user wants to LOOP or STOP when the MAXFILES is reached:
LOOPACTION="LOOP"

	#Define the 'FILECOUNT' variable as being the number of files (loosely speaking) currently found in the recording directory:
	FILECOUNT=`ls $path/*.mp3 | wc -l`
	echo "Filecount = $FILECOUNT"
	echo "Maxfiles = $MAXFILES"

	#Now to compare the actual recorded filecount with our chosen maximum:
	if [ $FILECOUNT -ge $MAXFILES ];
	then
	#Determine name of oldest file in storage directory
	#Syntax from Gilles here:http://unix.stackexchange.com/questions/26437/access-the-last-file-alphabetically-in-a-directory:
	OLDESTFILENAME=`ls $path/*.mp3 | head -n 1`
	#previous syntax 	OLDESTFILENAME=`ls -t $path | tail -n 1`
	echo "Removing $OLDESTFILENAME"
	#Test for user decision whether to LOOP or STOP when MAXFILES is reached:
	if [ $LOOPACTION = "STOP" ];
	then
	echo "Stopping"
	gxmessage 'MAXFILES reached. Recording has been stopped.

User has set LOOPACTION=STOP.
Looping and overwriting of older files is not
performed unless user sets LOOPACTION=LOOP ' \
          -bg "#FF3636" \
          -center \
          -buttons "Click to terminate":1 \
          -geometry 400x80 \
          -name "mictrapper STOPPED"  &
	exit
	
	else
	rm $OLDESTFILENAME
	#Advise user that we are removing the oldest file:
	gxmessage " 
   
       ... Oldest file deleted ...    " -center -bg "#FC8E3B" -buttons , -timeout 3 -name  "BUFFER LOOPING" &
       #dull blue = "#446a7e", orange="#FF6D00"
	fi

	else
		gxmessage "   
       ... Recording new files ...    " -center -bg "#0AFC11" -buttons , -timeout 3 -name  "RECORDING" &
fi;

	yaf-splash -close never -bg green -placement top -timeout $RECORDINGLENGTH -display :0 -text "Recording....."  &
	#Set up recording filename parameters:
	NAME=`date +%Y-%m-%d_%H-%M-%S`
	#The arecord syntax can be changed to get the best out of your specific soundcard.
	#Otherwise just run with the default used below:
	#The following syntax gives lots of hiss on some systems:
	#arecord -f S16_LE -c1 -r22050 -d $RECORDINGLENGTH -t raw | lame -r -s 22.05 -m m -b $MP3BITRATE - $path/$NAME.mp3
	#The following syntax gives great default quality but large file size:
	#arecord -f dat -d $RECORDINGLENGTH -D hw:0,0 $path/$NAME.wav
	#The following syntax suggested by mikeb seems to give good balance of filesize and quality.
	arecord -d $RECORDINGLENGTH -V mono -D plughw:0,0 -f cd | lame -b $MP3BITRATE - $path/$NAME.mp3

 done

User avatar
mikeb
Posts: 11297
Joined: Thu 23 Nov 2006, 13:56

#41 Post by mikeb »

Well when you are comfortable with it perhaps make a thread in the software section since it seems to me it could be useful to others.

Some may also take up the gui for you thats more familiar with gtkdialog too

mike

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#42 Post by greengeek »

mikeb wrote:Well when you are comfortable with it perhaps make a thread in the software section since it seems to me it could be useful to others.
Done. I have added an interactive phase where it asks the user to specify a suitable storage location (which might be a dedicated external usb drive for example). Thanks everyone for the ideas and encouragement with this - I've ended up with something which is quite useful even in it's current form and learnt a lot on the way. cheers!

I have plans to alter the script further to allow more automatic methods of space limitation and a few other features. I will probably continue developing those techniques back in this thread rather than the new one. This can be where i privately stumble over my bash programming :-) ("baby-bashing")

New thread here

Post Reply