Software-Experimente mit Linux

Musikwiedergabe über PC und Mac
Martin
Aktiver Hörer
Beiträge: 99
Registriert: 15.03.2012, 14:23

Beitrag von Martin »

Hallo Frank,
vielen Dank für Deine ausführliche Antwort. Bei dem Test mit den "date"-Befehlen kommen bei mir auch Zeiten im Millisekundenbereich heraus. Zwar etwa 2-3 mal so langsam wie bei Dir, aber ich habe auch einen relativ langsamen Server-PC. Bei näherem Hinsehen bzw. Hinhören passiert die Verzögerung auch nicht beim Starten der Playlist, sondern erst beim Hin- und Herzappen innerhalb der Playlist. Wenn ich also mitten im aktuellen Stück zum nächsten Stück wechseln möchte, dann wird das aktuelle Stück noch etwa 3 Sekunden weitergespielt, obwohl der Fortschrittsbalken auf dem Android-Tablet dann schon die ersten 3 Sekunden vom nächsten Stück anzeigt.
Ähnliches passiert auch bei Variante mit sox an Stelle von mpd. Der Startvorgang geht schnell, wenn ich jedoch auf dem Server-PC das sox | nc Skript mit Strg-C abbreche, spielt der Audio-PC noch etwa 2 Sekunden nach.
Das alles stört wirklich nur, wenn man am Hin- und Herzappen ist. Normalerweise macht man das ja auch nicht, aber hin und wieder ist es zum Testen ganz hilfreich.

Viele Grüße
Martin
Bild
frankl
Aktiver Hörer
Beiträge: 418
Registriert: 20.01.2013, 01:43
Wohnort: Aachen

Beitrag von frankl »

Martin hat geschrieben: Bei näherem Hinsehen bzw. Hinhören passiert die Verzögerung auch nicht beim Starten der Playlist, sondern erst beim Hin- und Herzappen innerhalb der Playlist. Wenn ich also mitten im aktuellen Stück zum nächsten Stück wechseln möchte, dann wird das aktuelle Stück noch etwa 3 Sekunden weitergespielt, obwohl der Fortschrittsbalken auf dem Android-Tablet dann schon die ersten 3 Sekunden vom nächsten Stück anzeigt.
Ähnliches passiert auch bei Variante mit sox an Stelle von mpd. Der Startvorgang geht schnell, wenn ich jedoch auf dem Server-PC das sox | nc Skript mit Strg-C abbreche, spielt der Audio-PC noch etwa 2 Sekunden nach.
Hallo Martin,

was Du beschreibst zeigt doch, dass eines der beteiligten Programme auf dem Audio-PC einen größeren Puffer hat (wie gesagt, die Standardpuffer in den Pipes sollten hier vernachlässigbar sein).

Benutzt Du 'aplay' zum eigentlichen Abspielen? Ich weiß jetzt nicht, wie groß dessen Buffer standardmäßig ist. Es kann aber lohnen mit den Buffergrößen in 'aplay' etwas zu experimentieren. Als ich 'aplay' noch benutzt habe, fand ich das Ergebnis gut, wenn die '-F' Option mit einem möglichst kleinen Wert (so, dass es noch geht) benutzt wurde, auch '-M' kann man probieren.

Außerdem kannst Du mal versuchen, dem eigentlichen Abspielprogramm (also 'aplay' oder was Du benutzt) auf dem Audiorechner eine hohe Priorität unter dem "real time scheduler" zu geben. Das geht mit dem 'chrt' Kommando. Dieses kann eventuell nur mit root-Rechten gemacht werden, dann entweder das Programm
auf dem Audio-Rechner als 'root' starten (das gehört sich eigentlich nicht) oder 'chrt' als "setuid" markieren
(mit "chmod 4755 /usr/bin/chrt". Dann zum Beispiel 'aplay' mit

Code: Alles auswählen

chrt -r 99 aplay .....

aufrufen.

Viele Grüße,
Frank
Bild
Martin
Aktiver Hörer
Beiträge: 99
Registriert: 15.03.2012, 14:23

Beitrag von Martin »

Hallo Frank,
vielen Dank für die Tipps. Mittlerweile läuft die Konfiguration mit Server-PC( mpd) und Audio-PC (aplay) schon ganz gut.
Der Server-PC macht das Upsampling auf 88.2 kHz sowie die Filterung mit 'brutefir' und schickt die Daten mit 'nc' an den Audio-PC, der mit 'aplay' die Daten an den asynchronen D/A-Wandler (USB-Audio Class 1) mit 88,2 kHz und 24 Bit ausgibt. Gerne würde ich auch mal deine Player-Software testen, falls frei verfügbar.

Übrigens habe ich mittlerweile das Aria-Board bekommen. Vielleicht schaffe ich es über Weihnachten alles zusammen zu bauen. Den DAC wollte ich bei der Gelegenheit auch noch etwas optimieren.

Viele Grüße
Martin
Bild
Daihedz
Aktiver Hörer
Beiträge: 737
Registriert: 25.06.2010, 15:09

Beitrag von Daihedz »

Hallo Frank und andere Pinguinophile

Ich habe aufgrund Deines wertvollen Inputs etwas gescriptet und habe mir einen Server und einen Client zusammengeschustert, welche miteinander über
<datei> -> sox (mit Upsampling) -> ncat ...... ncat -> sox -> audioausgabe
funktionieren.

Serverseitig sendet Ncat über einen Port den Audiostream, und stellt über einen anderen Port Infos über den audiostream und den server zur Verfügung. Wenn der Server beendet wird, resp. nicht mehr sendet, geht der Client in eine Warteposition, und umgekehrt, wenn der Client beendet wird, dann stört dies den Server auch nicht sonderlich. Er sendet den Audiostream mit den dazu gehörigen Informationen einfach weiter. Das ganze ist noch eine ziemliche Baustelle, funktioniert aber doch schon recht gut. Aber eben, es fehlen noch Komfortfunktionen:

Sox benötigt so zum Beipiel im Aufruf den Namen der abzuspielenden Datei. Frage nun: Kennt jemand eine bequeme Lösung, um Unterverzeichnisse (mit den Audiodateien) in einer Art Datenbank zu verwalten? Natürlich würde es z.B. auch ein midnight commander tun, um herumzunavigieren, aber eben, ich wünsche mir so eine Verwaltung, gerne auch in abgespeckter Version, wie sie in media playern à la vlc oder foobar zur Verfügung steht. Z.B. könnte es auch ein zweckentfemdeter Fotosammlungsmanager tun.

Any Ideas?
Simon

Im Anhang noch der aktuelle Stand des Irrtums ...

Server:

Code: Alles auswählen

#!/bin/bash
########
# muzzir
# Muzik Zirver
########
#
# Simon
# 18.1.2014 / 00:00
# Version 0.0.6


# Variables I - user defined

AUDIO_USER="privat"

AUDIOFILES_SOURCE_SWITCH="drive"	# "ramdisk" / "drive"

AUDIOSTREAM_BITS="32"
AUDIOSTREAM_CONTENT_PORT="3456"
AUDIOSTREAM_CONTENT_SWITCH="single"	# "single" / "context" #### TODO #### : / "next" / "previous"
AUDIOSTREAM_INFO_PORT="3457"
AUDIOSTREAM_SAMPLERATE="96000"

### Variables II - ! DO NOT MODIFY THEM !

AUDIOFILE="$1"
AUDIOFILE_BASENAME=$(basename "${AUDIOFILE}")
AUDIOFILE_DIRNAME=$(dirname "${AUDIOFILE}")

AUDIOFILE_COMPOSER=$(basename "$(dirname "${AUDIOFILE_DIRNAME}")")
AUDIOFILE_CONTEXT=$(basename "${AUDIOFILE_DIRNAME}")
AUDIOFILE_EXTENSION=${AUDIOFILE_BASENAME##*.}
AUDIOFILE_TITLE=${AUDIOFILE_BASENAME%.*}

AUDIOFILES_SELECTION="void"
AUDIOFILES_SELECTION_TEXT="void"
AUDIOFILES_SOURCE=${AUDIOFILE_DIRNAME}
AUDIOFILES_SOURCE_TEXT="void"

AUDIOSTREAM_CONTENT_INFO="void"
AUDIOSTREAM_INFO_FILE="muzzir_audiostream.info"

RAMDISK="/var/tmp/${AUDIO_USER}/ramdisk"
SHELL_PIDS_FILE="muzzir_shellpid.info"
TEMPDIR="/var/tmp/${AUDIO_USER}"


### Functions


function delay_apply() {

	if [ ${DA_MODE} = "hold_till_started" ] ; then

		# Delay until complete startup of $DA_SUBJECT

		DA_LOOP=0

		while true ; do

			(( DA_LOOP += 1 ))

			sleep ${DA_DELAY_INCREMENT}
			
			if [ $(pidof "${DA_SUBJECT}" | wc -w) -gt "${DA_SUBJECT_PIDS_COUNT}" ] ; then

				break
			fi
			
			if [ ${DA_LOOP} = 20 ] ; then
				# emergency exit
				
				echo "--- WARNING: BUGGY CODE in muzzir ---"
				echo "--- Funcion [delay_apply] '${DA_MODE}': Forced exit performed on ${DA_SUBJECT} after ${DA_LOOP} loops ---"
				break
			fi
		done
		
	elif [ ${DA_MODE} = "hold_till_null" ] ; then

		# Hold bash open until $DA_SUBJECT is closed / killed

		DA_LOOP=0	

		while true ; do

			(( DA_LOOP += 1 ))
			
			sleep ${DA_DELAY_INCREMENT}

			if [ $(pidof "${DA_SUBJECT}" | wc -w) -eq 0 ] ; then

				break
			fi

			if [ ${DA_LOOP} = 20 ] ; then
				# emergency exit
				
				echo "--- WARNING: BUGGY CODE in muzzir ---"
				echo "--- Funcion [delay_apply] '${DA_MODE}': Forced exit performed on ${DA_SUBJECT} after ${DA_LOOP} loops ---"
				break
			fi
		done

	elif [ ${DA_MODE} = "hold_till_null_PID" ] ; then

		# Hold bash open until $DA_SUBJECT (=PID) is closed / killed

		DA_LOOP=0

		while true ; do

			(( DA_LOOP += 1 ))
			
			sleep ${DA_DELAY_INCREMENT}

			if ! [ $(ps -p "${DA_SUBJECT}" > /dev/null) ] ; then

				break
			fi
			
			if [ ${DA_LOOP} = 20 ] ; then
				# emergency exit
				
				echo "--- WARNING: BUGGY CODE in muzzir ---"
				echo "--- Funcion [delay_apply] '${DA_MODE}': Forced exit performed on ${DA_SUBJECT} after ${DA_LOOP} loops ---"
				break
			fi
		done
	fi
}


function infos_get () {
	# Purpose: Display infos on the console about state of server

	# Streaming content

	if [ ${AUDIOSTREAM_CONTENT_SWITCH} = "context" ] ; then

		AUDIOFILES_SELECTION="*.${AUDIOFILE_EXTENSION}"
		AUDIOFILES_SELECTION_TEXT="Streaming full content of ${AUDIOFILE_BASENAME}"
		
		AUDIOSTREAM_CONTENT_INFO="Content: ${AUDIOFILE_COMPOSER} --- ${AUDIOFILE_CONTEXT}"

	elif [ ${AUDIOSTREAM_CONTENT_SWITCH} = "single" ] ; then

		AUDIOFILES_SELECTION="${AUDIOFILE_BASENAME}"
		AUDIOFILES_SELECTION_TEXT="Streaming single track/file"
		
		AUDIOSTREAM_CONTENT_INFO="Content: ${AUDIOFILE_COMPOSER} --- ${AUDIOFILE_CONTEXT} --- ${AUDIOFILE_TITLE}"
	
	else

		AUDIOFILES_SELECTION="${AUDIOFILE_BASENAME}"
		AUDIOFILES_SELECTION_TEXT="Streaming single track/file"
		
		AUDIOSTREAM_CONTENT_INFO="Content: ${AUDIOFILE_COMPOSER} --- ${AUDIOFILE_CONTEXT} --- ${AUDIOFILE_TITLE}"
	fi

	# Audiostream format assessing

	$(sox -V3 "${AUDIOFILES_SOURCE}"/"${AUDIOFILES_SELECTION}" -b ${AUDIOSTREAM_BITS} -t raw -n trim 0 1 rate -s -v -I ${AUDIOSTREAM_SAMPLERATE} 2> ${AUDIOSTREAM_INFO_FILE})
	
	AUDIOSTREAM_CHANNELS=$(cat ${AUDIOSTREAM_INFO_FILE} | grep "Output File" -A 7 | grep "Channels" | cut -d ":" -f 2 | tr -d " ")
	AUDIOSTREAM_ENCODING=$(cat ${AUDIOSTREAM_INFO_FILE} | grep "Output File" -A 7 | grep "Endian Type" | cut -d ":" -f 2 | tr -d " ")
	
	AUDIOSTREAM_FORMAT_INFO="Channels: ${AUDIOSTREAM_CHANNELS}   Samplesize/Bits: ${AUDIOSTREAM_BITS}   Samplerate: ${AUDIOSTREAM_SAMPLERATE}   Encoding/Endianness: ${AUDIOSTREAM_ENCODING}   ContentStreamPort: ${AUDIOSTREAM_CONTENT_PORT}" 
}


function infos_print () {
	# Purpose: Display infos on the console about state of server

	# Info
	
	clear
	echo "--- STREAMING CONTENT ---"
	echo ""
	echo "${AUDIOSTREAM_CONTENT_INFO}"
	echo ""
	echo ${AUDIOFILES_SELECTION_TEXT}
	echo ${AUDIOFILES_SOURCE_TEXT}
	echo ""
	echo ""
	echo "--- AUDIOSTREAM FORMAT ---"
	echo ""
	echo "${AUDIOSTREAM_FORMAT_INFO}"
	echo ""
}


function ramdisk_tempdir_setup() {

	# Only set up ramdisk if option is selected

	if [ ${AUDIOFILES_SOURCE_SWITCH} = "ramdisk" ] ; then

		clear
		echo "--- SETTING UP RAMDISK ---"

		if ! [ -d ${RAMDISK} ] ; then
	
			mkdir ${RAMDISK}
			mount -t ramfs ${RAMDISK}

			FSTAB_STRING="ramfs    "${RAMDISK}"    ramfs    defaults    0    0"

			if [ $(cat /etc/fstab | grep "${RAMDISK}" | wc -w) -eq 0 ] ; then

				sudo chown ${AUDIO_USER} /etc/fstab
				echo $FSTAB_STRING >> /etc/fstab
				echo "" >> /etc/fstab
			fi
		fi
	
		sudo chown ${AUDIO_USER} ${RAMDISK}

		rm -fr ${RAMDISK}/*.mp3 > /dev/null
		rm -fr ${RAMDISK}/*.flac > /dev/null
		rm -fr ${RAMDISK}/*.wav > /dev/null
	fi

	# Audio- and Infofiles Ramdisk/Tempdir Source
	
	if [ -d ${RAMDISK} ] ; then
		# Creation of Ramdisk has been successful
			
		# Files to copy
	
		if [ ${AUDIOSTREAM_CONTENT_SWITCH} = "context" ] ; then

			cp "${AUDIOFILE_DIRNAME}"/*.${AUDIOFILE_EXTENSION} ${RAMDISK}

		elif [ ${AUDIOSTREAM_CONTENT_SWITCH} = "single" ] ; then
	
			cp "${AUDIOFILE}" ${RAMDISK}
		else
	
			echo "" > /dev/null
		fi			

		# Definition of audiofiles source and helper files directory
		
		AUDIOFILES_SOURCE=${RAMDISK}
		AUDIOFILES_SOURCE_TEXT=" Streaming Source: RAM disk"

		AUDIOSTREAM_INFO_FILE="${RAMDISK}/${AUDIOSTREAM_INFO_FILE}"
		SHELL_PIDS_FILE="${RAMDISK}/${SHELL_PIDS_FILE}"

	else
		# No Ramdisk

		# Read files from where they originally are

		AUDIOFILES_SOURCE=${AUDIOFILE_DIRNAME}
		AUDIOFILES_SOURCE_TEXT="Streaming Source: Original files carrier medium (no RAM disk streaming)"

		# Create temporary directoy

		if ! [ -d ${TEMPDIR} ] ; then

			mkdir ${TEMPDIR}
		fi

#		sudo chown ${AUDIO_USER} ${TEMPDIR}

		AUDIOSTREAM_INFO_FILE="${TEMPDIR}/${AUDIOSTREAM_INFO_FILE}"
		SHELL_PIDS_FILE="${TEMPDIR}/${SHELL_PIDS_FILE}"
	fi
}


function start_ncat () {
	# Purpose: Start SOX streaming

	# Begin staring sequence
	
	# Kill already running muzzir shell and reset new information

	if [ -a "${SHELL_PIDS_FILE}" ] ; then

		kill $(cat "${SHELL_PIDS_FILE}") &> /dev/null

		if [ $? = 0 ] ; then

			DA_DELAY_INCREMENT="0.1"
			DA_MODE="hold_till_null_PID"
			DA_SUBJECT=$(cat "${SHELL_PIDS_FILE}")

			delay_apply

			DA_DELAY_INCREMENT=""
			DA_MODE=""
			DA_SUBJECT=""
			
			rm -f ${SHELL_PIDS_FILE}
		fi
	fi

	echo $$ > ${SHELL_PIDS_FILE}


	# Kill ncat instances

	killall ncat

	if [ $? = 0 ] ; then

		DA_DELAY_INCREMENT="0.1"
		DA_MODE="hold_till_null"
		DA_SUBJECT="ncat"

		delay_apply

		DA_DELAY_INCREMENT=""
		DA_MODE=""
		DA_SUBJECT=""
	fi
	

	# Start Audiostream / SOX

	$(sox "${AUDIOFILES_SOURCE}"/"${AUDIOFILES_SELECTION}" -b ${AUDIOSTREAM_BITS} -t raw - rate -s -v -I ${AUDIOSTREAM_SAMPLERATE} | ncat -l -k -p ${AUDIOSTREAM_CONTENT_PORT}) &

	# Cycle broadcast infos about the server and the audio stream

	NCAT_PIDS_COUNT_POSTSTART=9999
	NCAT_PIDS_COUNT_PRESTART=999
	
	NCAT_START_SWITCH="start"
	
	while true ; do

		if [ ${NCAT_START_SWITCH} = "start" ] ; then

			NCAT_PIDS_COUNT_PRESTART=$(pidof ncat | wc -w)
		
			echo "${AUDIOSTREAM_FORMAT_INFO} ${AUDIOSTREAM_CONTENT_INFO}" | ncat -l -p ${AUDIOSTREAM_INFO_PORT} &
			
			NCAT_START_SWITCH="hold"

			NCAT_PIDS_COUNT_POSTSTART=$(pidof ncat | wc -w)
		else
		
			if [ $(pidof ncat | wc -w) -lt ${NCAT_PIDS_COUNT_POSTSTART} ] ; then
				# Infos have been read and most probabls nc for infos broadcast has shut down

				NCAT_START_SWITCH="start"
			fi
		fi

		sleep 0.5
	done

	
	# Reset variables
	
	NCAT_PIDS_COUNT_POSTSTART=""
	NCAT_PIDS_COUNT_PRESTART=""
}



### Main Program

# Check for proper invocation of program

if ! [ -a "${AUDIOFILE}" ] ; then

	clear
	echo "No Audiofile selected"
	sleep 5

	exit
fi


# Setup ramdisk

ramdisk_tempdir_setup

# Getting and displaying infos about the stream

infos_get

infos_print


# Startup sequence

start_ncat
Client:

Code: Alles auswählen

#!/bin/bash
########
# muzkli
# Muzik Klient
########
#
# Simon
# 27.1.2014 / 00:00
# Version 0.0.6


# TODO : Cyklische Info von NC unterdrücken



# Variables

AUDIOSTREAM_INFO_PORT="3457"
AUDIOSTREAM_SERVER_URL="127.0.0.1"
AUDIOSTREAM_OUTPUT="alsa hw:1"

LOOP_COUNT=0
LOOP_STATUS="server_quiet"

while true ; do

	AUDIOSTREAM_INFO=$(nc --recv-only -i 0.25 "${AUDIOSTREAM_SERVER_URL}" "${AUDIOSTREAM_INFO_PORT}")

	echo $AUDIOSTREAM_INFO

	if [ -n "${AUDIOSTREAM_INFO}" ] ; then
		# There is (new or changed) information from the server
		
		AUDIOSTREAM_INFO_BITS=""
		AUDIOSTREAM_INFO_CHANNELS=""
		AUDIOSTREAM_INFO_CONTENT=""
		AUDIOSTREAM_INFO_CONTENT_PORT=""
		AUDIOSTREAM_INFO_ENCODING=""
		AUDIOSTREAM_INFO_SAMPLERATE=""

		LOOP_COUNT=0
		
		# Audiostream information decoding
	
		ITEM="null"
		ITEM_NEXT="null"
		
		for ITEM in ${AUDIOSTREAM_INFO} ; do

			# Translate Audiostream sequence into variables

			if [[ ${ITEM_NEXT} = "BITS" || ${ITEM_NEXT} = "CHANNELS" || ${ITEM_NEXT} = "CONTENT_PORT" || ${ITEM_NEXT} = "SAMPLERATE" ]] ; then

				declare -g "AUDIOSTREAM_INFO_${ITEM_NEXT}"="$ITEM"

				ITEM_NEXT="null"
				
			elif [ ${ITEM_NEXT} = "ENCODING" ] ; then
			
				if [ ${ITEM} = "little" ] ; then
				
					AUDIOSTREAM_INFO_ENCODING="si"
				else
				
					echo "!!!! unknown Encoding: ${ITEM} !!!!"
				fi

				ITEM_NEXT="null"
				
			elif [ ${ITEM_NEXT} = "CONTENT" ] ; then
			
				AUDIOSTREAM_INFO_CONTENT="${AUDIOSTREAM_INFO_CONTENT} "${ITEM}
			fi			
		
	
			if [ ${ITEM} = "Channels:" ] ; then
			
				ITEM_NEXT="CHANNELS"
				
			elif [ ${ITEM} = "Encoding/Endianness:" ] ; then
			
				ITEM_NEXT="ENCODING"
				
			elif [ ${ITEM} = "Samplesize/Bits:" ] ; then
			
				ITEM_NEXT="BITS"
				
			elif [ ${ITEM} = "Samplerate:" ] ; then
			
				ITEM_NEXT="SAMPLERATE"
				
			elif [ ${ITEM} = "ContentStreamPort:" ] ; then

				ITEM_NEXT="CONTENT_PORT"
				
			elif [ ${ITEM} = "Content:" ] ; then
			
				ITEM_NEXT="CONTENT"
			fi
	
		done
		
		# Check wheter audiostream info for $CONTENT_PORT value

		if [[ -n ${AUDIOSTREAM_INFO_CONTENT_PORT} && ${AUDIOSTREAM_INFO_CONTENT_PORT} -gt 1000 && ${AUDIOSTREAM_INFO_CONTENT_PORT} -lt 9999 ]] ; then

			# Server is streaming
		
			(( LOOP_COUNT += 1 ))
		
			if [ ${LOOP_COUNT} = 1 ] ; then

				LOOP_STATUS="server_streaming"
				
				clear
				echo "--- SERVER IS STREAMING ---"
				echo ""

				echo "CONTENT: " $AUDIOSTREAM_INFO_CONTENT

				echo ""
				echo ""
				echo "--- STATUS ---"

				nc "${AUDIOSTREAM_SERVER_URL}" "${AUDIOSTREAM_INFO_CONTENT_PORT}" | sox -t raw -b "${AUDIOSTREAM_INFO_BITS}" -e ${AUDIOSTREAM_INFO_ENCODING} -r "${AUDIOSTREAM_INFO_SAMPLERATE}" -c ${AUDIOSTREAM_INFO_CHANNELS} - -t ${AUDIOSTREAM_OUTPUT} &
			fi
		fi
	fi

	if [ ${LOOP_STATUS} = "server_quiet" ] ; then
		
		clear
		echo "--- SERVER IS QUIET - NO AUDIO STREAM AVAILABLE ---"
		date -R
	fi
	
	sleep 1
done

LOOP_COUNT=""
LOOP_STATUS=""
Bild
frankl
Aktiver Hörer
Beiträge: 418
Registriert: 20.01.2013, 01:43
Wohnort: Aachen

Beitrag von frankl »

Daihedz hat geschrieben:Hallo Frank und andere Pinguinophile

Ich habe aufgrund Deines wertvollen Inputs etwas gescriptet und habe mir einen Server und einen Client zusammengeschustert, welche miteinander über
<datei> -> sox (mit Upsampling) -> ncat ...... ncat -> sox -> audioausgabe
funktionieren.
Hallo Simon,

sieht doch schon gut aus!
Daihedz hat geschrieben: Das ganze ist noch eine ziemliche Baustelle, funktioniert aber doch schon recht gut. Aber eben, es fehlen noch Komfortfunktionen:

Sox benötigt so zum Beipiel im Aufruf den Namen der abzuspielenden Datei. Frage nun: Kennt jemand eine bequeme Lösung, um Unterverzeichnisse (mit den Audiodateien) in einer Art Datenbank zu verwalten? Natürlich würde es z.B. auch ein midnight commander tun, um herumzunavigieren, aber eben, ich wünsche mir so eine Verwaltung, gerne auch in abgespeckter Version, wie sie in media playern à la vlc oder foobar zur Verfügung steht. Z.B. könnte es auch ein zweckentfemdeter Fotosammlungsmanager tun.

Any Ideas?
Meine Variante in einer interaktiven Shell wirst Du wohl nicht als "Komfort" sehen, aber vielleicht ist eine Idee für Dich dabei. Ich mache mir eine Datei, in der die Namen der Verzeichnisse mit Musikdateien stehen, etwa so:

Code: Alles auswählen

 find mein/musik/dir -name \*\.flac  > index 
(Die Verzeichnisnamen sind aussagekräftig, z.B. "CDs/DavidMurrayBlackSaintQuartet_GilchristShahidDrake_LiveInBerlin/".) Zum Abspielen benutze ich zuerst zum Auswählen zum Beispiel

Code: Alles auswählen

grep Murray index
# oder zum Stöbern:
shuf -n30 index
Und dann rufe ich mein 'play'-Skript mit dem gewüschten Verzeichnis auf.

Ein Ansatz für das, was Du für eine interaktive Auswahl suchst, ist das Tool

Code: Alles auswählen

iselect -a < index
das man auch gut aus einem Skript aufrufen kann. Mir ist es aber nicht gut genug, ich hätte da gerne eine Such- und Auswahl-Möglichkeit eingebaut. Ohne das ist es eigentlich nur brauchbar, wenn der Input nur aus übersichtlich vielen Zeilen besteht (und nicht für meine lange Datei 'index').

Viele Grüße,
Frank

PS: Ich benutze mittlerweile meist ein komfortableres Programm, aber das möchte ich hier nicht propagieren, da es auf einem mächtigen und großen Programmpaket aufsetzt, dessen Installation Overkill ist, wenn man es nicht sowieso für anderes braucht.
Bild
wolfgangwolfi09
Aktiver Hörer
Beiträge: 65
Registriert: 11.07.2012, 14:39

Beitrag von wolfgangwolfi09 »

DAs ganze nützt doch nur wenn man diese ganzen Skripte auf Github oder Sourceforge stellt.
Und Programmier Cracks wie z.b bei AP linux , AV linux, Daphile, Volumino, RuneAudio überzeugt bekommt das sie dieses einbauen.
Einen kleinen aber wohl veralteten Ansatz gibt es ja für DRC hier
http://drconpendrive.com/drcop/user_man ... DRCoP.html
http://drconpendrive.com/mambo/index.ph ... &Itemid=42
Denn wenn es möglich ist per MiniDSP open DRC das ganze auf sehr kleiner Hardware laufen zu lassen dann müsste das ganze doch für einen sagen wir mal I3 kein Problem sein.
Diese Linuxdistribution sollte dann einfach alles enthalten und fix fertig installiert haben - was man so braucht an Installierten Scripten und Soundkarten managment und Treiber software.
In der Linux community tobt ja der streit um Jack und Alsa und weiss was ich noch alles.

Eben so an Abspielern - Clementine soll sehr gut sein Ammarok ist sehr beliebt MPD die Lösung für Daphile und eher minimalistische Distributionen wie Volumino oder Rune Audio.
Zur Formatwandlung kann man ja SOX nehmen und zum rippen weiss ich nicht was da aktuell so präferiert wird.
Letztlich muss man die abzuspielenden Files komplett in eine RAMDISK laden um so wenig wie möglich traffic und damit Kommunikationsmüll der sich klanglich schlecht auswirkt sich einzufangen.

Die Frage wäre wer von den Linux cracks kann das hier machen und ist man da wirklich interessiert dran ?

Denn das ganze muss ja für den User in irgend einer Form bedienbar sein.
OutoftheBox müssen so viele Soundkarten und DACs unterstützt werden Treiber mässig.
Ich wundere mich da dass z.b von der RME 9652 mit z.B ein oder zwei ADA 8000 kaum die Rede ist das wäre sehr gute Hardware mit gutem Sound oder auch die alten Motu 828 und 328 Plattformen.
Stattdessen wird mit überteuerten pseudo Hifi und Highend Interfaces und DACs herum laboriert.
Anstatt auf Studiotechnik zu setzen.
Bild
frankl
Aktiver Hörer
Beiträge: 418
Registriert: 20.01.2013, 01:43
Wohnort: Aachen

Beitrag von frankl »

Hallo Forenten,

am Anfang dieses Threads habe ich von Software-Experimenten zum Abspielen von Musik über Linux-Rechner berichtet. Ich habe nun die Funktionalität meiner Programm-Prototypen in wenigen Programmen konzentriert und noch etwas verbessert, diese mit (eingebauter) Dokumentation versehen, in ein paar Setups ausprobiert, und eine Webseite dazu gemacht. Darüber sind die Programme jetzt verfügbar (unter den Bedingungen der GPL).

Dort gibt es auch Seiten zu einigen Filtern, die ich beim Musik abspielen verwende. Diese sind im Moment recht kurz. Bei Interesse kann ich dort weitere Informationen, Code-Fragmente oder Filterdateien ergänzen.

Wie weiter oben im Thread schon erwähnt, habe ich kein fertiges Playerprogramm, das man runterlädt und dann einfach mit Musikdateien aufruft. Es handelt sich eher um Klötze in einem Baukasten, die man in individuell optimierten Skripten verwenden kann.

Für die Windows-Fans unter Euch ist das natürlich völlig uninteressant, schließlich habt Ihr ja gerade das zweite Mal(!) den heiligen Gral der Player-Software entdeckt . . .

Wer Interesse hat schaue [url=http://frank_l.bitbucket.org/stereoutils/index.html]hier[/url].

Viele Grüße,
Frank
Bild
Pittiplatsch
Aktiver Hörer
Beiträge: 452
Registriert: 26.02.2012, 10:48

Beitrag von Pittiplatsch »

Hallo Frank,

ich finde es super interessant und habe gerade mal gespielt und waere erstmal fast vom Stuhl gefallen nachdem ja aplay in nativlautstaerke ausgiebt :).
Hast du auch Erfahrung mit den etwas komfortableren playern? Ich suche noch nach etwas mit weitestgehend nativem Alsa - output und dem komfort von rhythmbox. Ich bin derzeit von rhythmbox auf audacious umgestigen, aber mir fehlt das komfortable Ordnungssystem nach Genres.... Bei rhythmbox habe ich mir eingebildet dass es sich wenn ich gstreamer auf alsa umleite trotzdem nicht so sauber klingt wie audacious (Einbildung???)

Viele Gruesse,
Tobias
Bild
Melomane
Aktiver Hörer
Beiträge: 1900
Registriert: 14.10.2011, 18:30

Beitrag von Melomane »

Hallo Tobias,

hast du schon mpd (viele Clients zur Bedienung, z.B. gmpc) oder squeezelite/Logitech Media Server (viel Komfort, zumal wenn mehrere Rechner/Räume bedient werden sollen) ausprobiert?

Gruß

Jochen
Bild
Pittiplatsch
Aktiver Hörer
Beiträge: 452
Registriert: 26.02.2012, 10:48

Beitrag von Pittiplatsch »

Hallo Jochen,

gmpc und mpd hoert sich ganz interessant an. Danke fuer den Tip. Das werde ich wohl mal an testen. Ich streame zu Hause eher nicht - ausser Filme und da schalte ich den Server nur fuer dir Dauer eines Filmes an. In meinen anderen Raeumen laeuft ganz altmodisch CD und LP.

Viele Gruesse,
Tobias
Bild
frankl
Aktiver Hörer
Beiträge: 418
Registriert: 20.01.2013, 01:43
Wohnort: Aachen

Beitrag von frankl »

Pittiplatsch hat geschrieben: ich finde es super interessant und habe gerade mal gespielt und waere erstmal fast vom Stuhl gefallen nachdem ja aplay in nativlautstaerke ausgiebt :).
Hallo Tobias,

wie bei jedem neuen Gerät (oder neuer Software) sollte man natürlich auch hier beim Testen zuerst den Lautstärkeknopf zurück drehen. Bzw., wenn man die Lautstärke per Software regelt, sollten meine Beispiele entsprechend verändert werden.

Pittiplatsch hat geschrieben: Hast du auch Erfahrung mit den etwas komfortableren playern? Ich suche noch nach etwas mit weitestgehend nativem Alsa - output und dem komfort von rhythmbox. Ich bin derzeit von rhythmbox auf audacious umgestigen, aber mir fehlt das komfortable Ordnungssystem nach Genres....
Wenn ich mal unterwegs mit Notebook und Kopfhörer Musik hören will, benutze ich seit Ewigkeiten audacious. Audiophil ist das natürlich indiskutabel und ich habe nie versucht, da etwas zu optimieren.
Und bei maximal 100 CDs auf der Festplatte brauche ich auch keine ausgefeilte Suchfunktion.
Pittiplatsch hat geschrieben: Bei rhythmbox habe ich mir eingebildet dass es sich wenn ich gstreamer auf alsa umleite trotzdem nicht so sauber klingt wie audacious (Einbildung???)
Nachdem ich gehört habe, wie dramatisch die Player-Software die Klangqualität verändern kann, halte ich es für plausibel, dass Du bei einigermaßen guter Wiedergabequalität Klangunterschiede zwischen Playern feststellen kannst.

Viele Grüße,
Frank
Bild
Daihedz
Aktiver Hörer
Beiträge: 737
Registriert: 25.06.2010, 15:09

Beitrag von Daihedz »

Hallo Frank

Zuerst mal mein persönliches Rating zu Deinem Input: AAA (unbedingt)

Und als zweites nun eine Frage zu Deinen Script-Beispielen auf
http://frank_l.bitbucket.org/stereoutils/player.html:
Du stellst in der Variante der FLAC-Datei -> Soundkarte zwei Möglichkeiten vor, eine FLAC-Datei nach stdout (->stdin) zu decodieren:
sox mymusic.flac -t raw - | \
playhrt --stdin --loops-per-second=1000 --device=hw:0,0 --sample-rate=44100 --sample-format=S16_LE

flac --totally-silent --force-raw-format --sign=signed --endian=little -d -c mymusic.flac |\
playhrt --stdin --loops-per-second=1000 --device=hw:0,0 --sample-rate=44100 --sample-format=S16_LE
In Deinem Streaming-Script jedoch bietest Du ausschliesslich die Lösung der FLAC-Dekodierung mittels flac (und nicht wie in den ersten Beispielen alternativ auch noch mit sox) an:
flac --totally-silent --force-raw-format --sign=signed --endian=little --skip=00:00.00 --until=-00:00.00 -d -c cd.flac | sox -t raw ...
Hat dies eine besondere Bewandtnis, oder ist dies eher eine zufällige Auswahl, resp ein zufälliger Entscheid? Oder anders herum gefragt: Hat in der streaming-variante flac vielleicht nach Deiner Erfahrung gegenüber sox einen Vorteil?

Und noch eine andere Frage: Ab Kernel 3.14 ist neu deadline scheduling implementiert. Bringt dies nach Deinem Dafürhalten Vorteile für Deine Programme, und falls ja: müssten in diesem Falle Deine Script-Beispiele etwas modifiziert werden, um das neue Feature zu nutzen?

Sehr angetan'e Grüsse
Simon
Bild
frankl
Aktiver Hörer
Beiträge: 418
Registriert: 20.01.2013, 01:43
Wohnort: Aachen

Beitrag von frankl »

Hallo Simon,

freut mich, wenn Du Spaß am Ausprobieren hast. Und natürlich noch mehr, wenn Du die Ergebnisse interessant findest.
Daihedz hat geschrieben: Und als zweites nun eine Frage zu Deinen Script-Beispielen auf
http://frank_l.bitbucket.org/stereoutils/player.html:
Du stellst in der Variante der FLAC-Datei -> Soundkarte zwei Möglichkeiten vor, eine FLAC-Datei nach stdout (->stdin) zu decodieren:
sox mymusic.flac -t raw - | \
playhrt --stdin --loops-per-second=1000 --device=hw:0,0 --sample-rate=44100 --sample-format=S16_LE

flac --totally-silent --force-raw-format --sign=signed --endian=little -d -c mymusic.flac |\
playhrt --stdin --loops-per-second=1000 --device=hw:0,0 --sample-rate=44100 --sample-format=S16_LE
In Deinem Streaming-Script jedoch bietest Du ausschliesslich die Lösung der FLAC-Dekodierung mittels flac (und nicht wie in den ersten Beispielen alternativ auch noch mit sox) an:
flac --totally-silent --force-raw-format --sign=signed --endian=little --skip=00:00.00 --until=-00:00.00 -d -c cd.flac | sox -t raw ...
Hat dies eine besondere Bewandtnis, oder ist dies eher eine zufällige Auswahl, resp ein zufälliger Entscheid? Oder anders herum gefragt: Hat in der streaming-variante flac vielleicht nach Deiner Erfahrung gegenüber sox einen Vorteil?
Klangmäßig kann ich keinen Unterschied zwischen sox und flac ausmachen. Der Grund, dass ich meist flac nutze ist implizit im zitierten Code gezeigt: für sox habe ich keine äquivalenten Optionen zu flac's --skip und --until gefunden. Ich habe bei mir komplette CDs ("bit-genau") in .flac Dateien gespeichert (zusammen mit .toc files als exaktes CD Backup). Meistens höre ich auch komplette CDs, aber wenn ich mal einzelne Stücke oder Ranges hören will, sind --skip und --until praktisch.

(Mein eigentliches (python-)Player Skript habe ich nicht erwähnt, da niemand sonst seine Musik so abgespeichert hat wie ich. Es spielt natürlich auch hires-Dateien, findet das Dateiformat der Quelle und eventuell die --skip und --until Argumente automatisch, und ruft meine Programme dann mit passenden Optionen auf.)
Daihedz hat geschrieben: Und noch eine andere Frage: Ab Kernel 3.14 ist neu deadline scheduling implementiert. Bringt dies nach Deinem Dafürhalten Vorteile für Deine Programme, und falls ja: müssten in diesem Falle Deine Script-Beispiele etwas modifiziert werden, um das neue Feature zu nutzen?
Gute Frage. Die Antwort weiß ich (noch) nicht. Vielleicht hast Du gesehen, dass mein Audio-Rechner so ein Aria G25 Board ist, von dem ich hier schon berichtet habe. Darauf benutze ich noch einen selbst cross-kompilierten 2.6.39 Kernel. Ich kann zwar einen neuen Kernel kompilieren, wie auf der Acme Seite beschrieben, aber wenn ich highres-timer einschalte bootet der nicht. Das wird meine nächste Software-Baustelle. Mit einem neueren Kernel hätte ich neuere Scheduler und eine neue ALSA Version - der USB Audio Treiber hat sich da auch stark geändert.

Wenn ich einen neuen Kernel habe, der läuft, werde ich mir das mit dem Scheduler ansehen, und auch versuchen, genauer zu verstehen, wie der USB-Audio Treiber funktioniert. Im Moment versuchen meine Programme ja nur, in möglichst exakten Intervallen die Audiodaten in den Buffer des Treibers zu schreiben.
Am Ende will ich aber, dass der Treiber in möglichst exakten Intervallen Daten an den DAC sendet. Mal sehen, ob da noch mehr drin ist.

Viele Grüße,
Frank
Bild
Daihedz
Aktiver Hörer
Beiträge: 737
Registriert: 25.06.2010, 15:09

Beitrag von Daihedz »

Hallo Frank

Ich experimentiere aktuell mit Deinen Linux-Lösungen:
frankl hat geschrieben: (in http://frank_l.bitbucket.org/stereoutils/player.html)

... Here is the code:

flac --totally-silent --force-raw-format --sign=signed --endian=little \
--skip=00:00.00 --until=-00:00.00 -d -c cd.flac | \
sox -t raw -r 44100 -c 2 -e signed -b 16 - -t raw -e floating-point -b 64 - | \
sox -t raw -c2 -r 44100 -e floating-point -b 64 - -t raw -e floating-point \
-b 64 - vol 0.4 rate -v -I 192000 | \
volrace -f /tmp/VOLRACE192 | \
brutefir /my/brutefir_config/S32_192.conf -quiet | \
writeloop --block-size=4096 --file-size=32000 /ramdisk/a1 /ramdisk/a2 \
/ramdisk/a3 &
...
In Deinem Beispiel wandelst Du mit einer ersten Instanz von SOX von 16Bit nach 64Bit, und dann mit einer gepipten zweiten Instanz von SOX von 44.1kHz nach 192kHz:
frankl hat geschrieben: ...
sox -t raw -r 44100 -c 2 -e signed -b 16 - -t raw -e floating-point -b 64 - | \
sox -t raw -c2 -r 44100 -e floating-point -b 64 - -t raw -e floating-point -b 64 - vol 0.4 rate -v -I 192000 | \
...
Frage nun: Warum machst Du die gesamte Wandlung nicht gleich in einem Rutsch, z.B. so:

sox -t raw -e signed -b 16 -r 44100 -c2 - -t raw -e floating-point -b 64 - vol 0.4 rate -v -I 192000

Das sollte eigentlich mit SOX doch möglich sein? Siehst Du vielleicht prinzipielle Vorteile bei Deiner gepipten Zwei-Sox-Einzelfunktions-Lösung gegenüber einer Ein-Sox-Doppelfunktions-Lösung? Es leuchtet mir schon ein, dass mit Deiner Lösung sichergestellt ist, dass auf alle Fälle 64-Bit-Daten zum Upsampling kommen, ditto zur Volumenregelung. Aber vielleicht ist diese Intelligenz in SOX bereits eingebaut? Weisst Du etwas davon?

Beste Grüsse
Simon
Bild
Daihedz
Aktiver Hörer
Beiträge: 737
Registriert: 25.06.2010, 15:09

Beitrag von Daihedz »

Hallo Frank - Take II

Zunächst sorry dafür, dass ich gleich zweimal hintereinader poste. Aber ich bin derart intensiv mit, und angetan von PLAYHRT und BUFHRT am experimentieren, dass sich die Fragen einfach nur so auftürmen...

Frage: Ist PLAYHRT und BUFHRT von der Theorie/Programmierung her einwandfrei dergestalt verwendbar, z.B. in einem 4-Weg-Stereo-Frequenzweichen-Rechner:

SOX (2-Kanal) | BUFHRT (2-Kanal) | BRUTEFIR (2-Kanal-in/8-Kanal-our)| PLAYHRT (8-Kanal) -> HW

Ich finde es phänomenal, welch mögliches Ausmass an präzisem Timing mit Playhrt verfügbar wird. Superissimo!!!

Begeisterte Grüsse
Simon
Bild
Antworten