profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/sentriz/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.
Senan Kelly sentriz @hipeople Dublin, Ireland https://senan.xyz previously @CPSSD, @aristanetworks | currently @hipeople backend engineer

sentriz/gonic 520

music streaming server / subsonic server API implementation

sentriz/fish-pipenv 171

🐟🐍 a fish plugin that automatically activates the pipenv subshell

sentriz/betanin 111

beets based mitm of your torrent client and music player

cpssd-students/steely 22

a python 3.6 facebook/telegram bot

sentriz/dotfiles 13

my dotfiles

sentriz/bandcamp_downloader 7

a python 3+ script for downloading, renaming, and tagging albums from Bandcamp

sentriz/compose-status 6

simple home server status page, compose and traefik aware

sentriz/hexchat_python_addons 5

a python 3+ collection of HexChat addons

sentriz/cliphist-sh 3

wayland clipboard manager

sentriz/cliphist 2

wayland clipboard manager

push eventsentriz/dotfiles

sentriz

commit sha ab8bf377a2b268aeb4f2c6c31f50cb32f33e7683

docs: add daw

view details

push time in a day

push eventsentriz/dotfiles

sentriz

commit sha e8ad578632072df7096b334aa5ebd629a57d2f5f

fish: add more VST3_PATH

view details

sentriz

commit sha ea558881c7c8d43e2482f739e6a6bf519a8618ef

block_playing: show browser playback

view details

sentriz

commit sha fd9d588f83d498fcdd5eac46078fd33fee152789

docs: add daw

view details

push time in a day

issue commentsentriz/gonic

support for prometheus-style metrics

Yeah cool idea. Would the output of using expvar be suitable?

https://pkg.go.dev/expvar

This would be then /debug/vars instead of /metrics

jelmer

comment created time in 4 days

startedtamland/airsonic-refix

started time in 5 days

startedRustAudio/rust-lv2

started time in 7 days

push eventsentriz/standardnotes-extensions

sentriz

commit sha 19df1d6f80f03fc41e5604d1bb66821ca8fa6b67

add new extensions Co-authored-by: Eric Pierce <eric@pierce.xyz>

view details

push time in 13 days

push eventsentriz/dotfiles

sentriz

commit sha 6401670dbb1d852e05a5491371aaa7807286f943

fish: add more VST_PATH/VST3_PATH https://developer.steinberg.help/display/VST/Plug-in+Locations#PluginLocations-FortheWindowsplatform https://developer.steinberg.help/display/VST/Plug-in+Locations#PluginLocations-ForLinuxplatform

view details

sentriz

commit sha 73f938a34da1020c48a6344ddcb1f2c6ebc067d3

sway: make qjackctl floating

view details

push time in 15 days

push eventsentriz/dotfiles

sentriz

commit sha c7757e49bb3378de218ce74da1abfe800b563656

fish: add more VST_PATH/VST3_PATH https://developer.steinberg.help/display/VST/Plug-in+Locations#PluginLocations-FortheWindowsplatform https://developer.steinberg.help/display/VST/Plug-in+Locations#PluginLocations-ForLinuxplatform

view details

sentriz

commit sha 6a4ed78935eca6b33d8e39d35aef0139d7c8349d

sway: make qjackctl floating

view details

push time in 15 days

push eventsentriz/dotfiles

sentriz

commit sha 2fae2a4901ec2b5b698dc2b134ba3215bc54c089

vim: update gopls_organise_imports

view details

sentriz

commit sha 07baf95a5a0dc9050eff6a29bc0b538ebbf112bd

fish: set VST_PATH to use yabridge

view details

sentriz

commit sha 9b6c07a79df6943299216ea1ac0144f33ec3c554

sway: remove wl-gammactld

view details

sentriz

commit sha 8c8ab4fcf1ff7076bc7e1f54bcd955fd1bbbf181

fish: escape nvim args in __super_vim

view details

sentriz

commit sha c0d454d14e4fb65b5c4c24fbb62a8b5c8e202fed

fish: configure more programs to use XDG dirs

view details

sentriz

commit sha 9046b3088508232c99a7483996195f8aff9d02c3

flatpak: setup bottles and insomnia

view details

sentriz

commit sha 5b68357614ee637ebaa2c7a2db4f0a5b601eb97d

fish: add more VST_PATH/VST3_PATH https://developer.steinberg.help/display/VST/Plug-in+Locations#PluginLocations-FortheWindowsplatform https://developer.steinberg.help/display/VST/Plug-in+Locations#PluginLocations-ForLinuxplatform

view details

push time in 23 days

push eventsentriz/cliphist

sentriz

commit sha c1457991f6b32f75c8af065627cf7d2820cf1d6b

add delete command

view details

push time in 24 days

push eventsentriz/nvim-lsp-compose

push time in a month

startedrobbert-vdh/yabridge

started time in a month

push eventsentriz/gonic

sentriz

commit sha ccc0e3c58d9fb1975bc0bdcf4f87829e9f705b74

fix(build): add zlib

view details

push time in a month

push eventsentriz/gonic

sentriz

commit sha 4d5c245872680dddce67c0a45afeb4346b6ba2e3

fix(build): add zlib

view details

push time in a month

startedtummychow/git-absorb

started time in a month

push eventsentriz/gonic

sentriz

commit sha c0ca6aaf0337a23b3f1d2a867884afe89fd4a281

fix(scanner): spawn interval scans in a goroutine this way, if the average scan takes longer than the tick interval, the ticker will be unblocked and scans won't stack on top of each other related #63

view details

push time in a month

Pull request review commentsentriz/gonic

feat(encode): rework encoding profiles to use true VBR and add optional upsample support

 func fileExists(filename string) bool {  func Profiles() map[string]Profile { 	return map[string]Profile{-		"mp3":     {"mp3", 128, []string{"-c:a", "libmp3lame"}, false},-		"mp3_rg":  {"mp3", 128, []string{"-c:a", "libmp3lame"}, true},-		"opus":    {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, false},-		"opus_rg": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, true},+		"mp3":      {"mp3", 128, []string{"-c:a", "libmp3lame"}, false, false, false},+		"mp3_rg":   {"mp3", 128, []string{"-c:a", "libmp3lame"}, true, false, false},+		"opus":     {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, false, false, false},+		"opus_rg":  {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, false, false},+		"opus_car": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, true, true},

I would be in favour of this :+1: seems nice a simple

though if it were a real yaml file, I'd be hesitant to add a second configuration file to gonic. maybe an idea could be to store the profiles as structs first? then later to make them configurable my the web UI. this would help with #121

spijet

comment created time in a month

PullRequestReviewEvent

Pull request review commentsentriz/gonic

feat(encode): rework encoding profiles to use true VBR and add optional upsample support

 func fileExists(filename string) bool {  func Profiles() map[string]Profile { 	return map[string]Profile{-		"mp3":     {"mp3", 128, []string{"-c:a", "libmp3lame"}, false},-		"mp3_rg":  {"mp3", 128, []string{"-c:a", "libmp3lame"}, true},-		"opus":    {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, false},-		"opus_rg": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, true},+		"mp3":      {"mp3", 128, []string{"-c:a", "libmp3lame"}, false, false, false},+		"mp3_rg":   {"mp3", 128, []string{"-c:a", "libmp3lame"}, true, false, false},+		"opus":     {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, false, false, false},+		"opus_rg":  {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, false, false},+		"opus_car": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, true, true},

ah good shout, thanks! then in that case, as we want to add more functionality to the ffmpegCommand function, it might get a bit complicated in future. what about a "functional options" pattern - where we can centralise the the different behaviours of each profile - and possibly make adding future functionality easier?

it could look something like this image

https://termbin.com/p7ee

(not at all tested, but just wondering if you like this idea)

spijet

comment created time in a month

PullRequestReviewEvent

Pull request review commentsentriz/gonic

feat(encode): rework encoding profiles to use true VBR and add optional upsample support

 func fileExists(filename string) bool {  func Profiles() map[string]Profile { 	return map[string]Profile{-		"mp3":     {"mp3", 128, []string{"-c:a", "libmp3lame"}, false},-		"mp3_rg":  {"mp3", 128, []string{"-c:a", "libmp3lame"}, true},-		"opus":    {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, false},-		"opus_rg": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, true},+		"mp3":      {"mp3", 128, []string{"-c:a", "libmp3lame"}, false, false, false},+		"mp3_rg":   {"mp3", 128, []string{"-c:a", "libmp3lame"}, true, false, false},+		"opus":     {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, false, false, false},+		"opus_rg":  {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, false, false},+		"opus_car": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, true, true},

yeah the enum is interesting. do you think something like this could work?

diff --git a/server/encode/encode.go b/server/encode/encode.go
index 550b6f7..58d0a0b 100644
--- a/server/encode/encode.go
+++ b/server/encode/encode.go
@@ -20,13 +20,20 @@ const (
 	ffmpeg  = "ffmpeg"
 )
 
+type ReplayGain int
+
+const (
+	RGNone ReplayGain = iota
+	RGForce
+	RGHigh
+)
+
 type Profile struct {
-	Format        string
-	Bitrate       int
-	ffmpegOptions []string
-	forceRG       bool
-	hiGainRG      bool
-	upsample      bool
+	Format     string
+	Bitrate    int
+	Options    []string
+	ReplayGain ReplayGain
+	Upsample   bool
 }
 
 func fileExists(filename string) bool {
@@ -39,11 +46,35 @@ func fileExists(filename string) bool {
 
 func Profiles() map[string]Profile {
 	return map[string]Profile{
-		"mp3":      {"mp3", 128, []string{"-c:a", "libmp3lame"}, false, false, false},
-		"mp3_rg":   {"mp3", 128, []string{"-c:a", "libmp3lame"}, true, false, false},
-		"opus":     {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, false, false, false},
-		"opus_rg":  {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, false, false},
-		"opus_car": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, true, true},
+		"mp3": {
+			Format:  "mp3",
+			Bitrate: 128,
+			Options: []string{"-c:a", "libmp3lame"},
+		},
+		"mp3_rg": {
+			Format:     "mp3",
+			Bitrate:    128,
+			Options:    []string{"-c:a", "libmp3lame"},
+			ReplayGain: RGForce,
+		},
+		"opus": {
+			Format:  "opus",
+			Bitrate: 96,
+			Options: []string{"-c:a", "libopus", "-vbr", "on"},
+		},
+		"opus_rg": {
+			Format:     "opus",
+			Bitrate:    96,
+			Options:    []string{"-c:a", "libopus", "-vbr", "on"},
+			ReplayGain: RGForce,
+		},
+		"opus_car": {
+			Format:     "opus",
+			Bitrate:    96,
+			Options:    []string{"-c:a", "libopus", "-vbr", "on"},
+			ReplayGain: RGHigh,
+			Upsample:   true,
+		},
 	}
 }
 
@@ -96,35 +127,34 @@ func ffmpegCommand(filePath string, profile Profile) (*exec.Cmd, error) {
 		"-vn",
 		"-b:a", fmt.Sprintf("%dk", profile.Bitrate),
 	}
-	args = append(args, profile.ffmpegOptions...)
-	if profile.forceRG {
-		aBaselineGain := 6
-		if profile.hiGainRG {
-			// This baseline gain results in final track being +3~5dB louder
-			// than Foobar2000's default ReplayGain target volume.
-			// This makes it easier to listen to music in a car, where all other
-			// sources are usually ten thousand times louder than RG-adjusted music.
-			// -- @spijet
-			aBaselineGain = 15
-		}
-		aFilters := []string{
-			fmt.Sprintf("volume=replaygain=track:replaygain_preamp=%ddB:replaygain_noclip=0", aBaselineGain),
-			"alimiter=level=disabled",
-			"asidedata=mode=delete:type=REPLAYGAIN",
-		}
+	args = append(args, profile.Options...)
 
-		// opus always forces output to 48kHz sampling rate, but we can still use upsampling
-		// to increase RG and alimiter's peak limiting precision, which is desirable in some
-		// cases. ffmpeg's `soxr` resampler is quite fast on x86-64: it takes around 5 seconds
-		// on my Ryzen 3600 to transcode an 8-minute FLAC with 2x upsample and RG applied.
+	var aFilters []string
+	// opus always forces output to 48kHz sampling rate, but we can still use upsampling
+	// to increase RG and alimiter's peak limiting precision, which is desirable in some
+	// cases. ffmpeg's `soxr` resampler is quite fast on x86-64: it takes around 5 seconds
+	// on my Ryzen 3600 to transcode an 8-minute FLAC with 2x upsample and RG applied.
+	// -- @spijet
+	if profile.Upsample {
+		aFilters = append(aFilters, "aresample=96000:resampler=soxr")
+	}
+
+	switch profile.ReplayGain {
+	case RGForce:
+		aFilters = append(aFilters, ffmpegPreamp(6)...)
+	case RGHigh:
+		// This baseline gain results in final track being +3~5dB louder
+		// than Foobar2000's default ReplayGain target volume.
+		// This makes it easier to listen to music in a car, where all other
+		// sources are usually ten thousand times louder than RG-adjusted music.
 		// -- @spijet
-		if profile.upsample {
-			aFilters = append([]string{"aresample=96000:resampler=soxr"}, aFilters...)
-		}
-		aFilterString := strings.Join(aFilters, ", ")
+		aFilters = append(aFilters, ffmpegPreamp(15)...)
+	}
+
+	if len(aFilters) > 0 {
 		args = append(args,
 			// set up replaygain processing
-			"-af", aFilterString,
+			"-af", strings.Join(aFilters, ", "),
 			// drop redundant replaygain tags
 			"-metadata", "replaygain_album_gain=",
 			"-metadata", "replaygain_album_peak=",
@@ -134,6 +164,7 @@ func ffmpegCommand(filePath string, profile Profile) (*exec.Cmd, error) {
 			"-metadata", "r128_track_gain=",
 		)
 	}
+
 	args = append(args, "-f", profile.Format, "-")
 	ffmpegPath, err := exec.LookPath(ffmpeg)
 	if err != nil {
@@ -144,6 +175,14 @@ func ffmpegCommand(filePath string, profile Profile) (*exec.Cmd, error) {
 	// but please do let me know if you see otherwise
 }
 
+func ffmpegPreamp(dB int) []string {
+	return []string{
+		fmt.Sprintf("volume=replaygain=track:replaygain_preamp=%ddB:replaygain_noclip=0", dB),
+		"alimiter=level=disabled",
+		"asidedata=mode=delete:type=REPLAYGAIN",
+	}
+}
+
 func encode(out io.Writer, trackPath, cachePath string, profile Profile) error {
 	// prepare cache part file path
 	cachePartPath := fmt.Sprintf("%s.part", cachePath)

image

spijet

comment created time in a month

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentsentriz/gonic

feat(encode): rework encoding profiles to use true VBR and add optional upsample support

 func ffmpegCommand(filePath string, profile Profile) (*exec.Cmd, error) { 	} 	args = append(args, profile.ffmpegOptions...) 	if profile.forceRG {+		aBaselineGain := 6+		if profile.hiGainRG {+			// This baseline gain results in final track being +3~5dB louder+			// than Foobar2000's default ReplayGain target volume.+			// This makes it easier to listen to music in a car, where all other+			// sources are usually ten thousand times louder than RG-adjusted music.+			// -- @spijet+			aBaselineGain = 15+		}+		aFilters := []string{+			fmt.Sprintf("volume=replaygain=track:replaygain_preamp=%ddB:replaygain_noclip=0", aBaselineGain),+			"alimiter=level=disabled",+			"asidedata=mode=delete:type=REPLAYGAIN",+		}++		// opus always forces output to 48kHz sampling rate, but we can still use upsampling+		// to increase RG and alimiter's peak limiting precision, which is desirable in some+		// cases. ffmpeg's `soxr` resampler is quite fast on x86-64: it takes around 5 seconds+		// on my Ryzen 3600 to transcode an 8-minute FLAC with 2x upsample and RG applied.+		// -- @spijet+		if profile.upsample {+			aFilters = append([]string{"aresample=96000:resampler=soxr"}, aFilters...)+		}

Gotcha thanks 👍

spijet

comment created time in a month

PullRequestReviewEvent

Pull request review commentsentriz/gonic

feat(encode): rework encoding profiles to use true VBR and add optional upsample support

 func ffmpegCommand(filePath string, profile Profile) (*exec.Cmd, error) { 	} 	args = append(args, profile.ffmpegOptions...) 	if profile.forceRG {+		aBaselineGain := 6+		if profile.hiGainRG {+			// This baseline gain results in final track being +3~5dB louder+			// than Foobar2000's default ReplayGain target volume.+			// This makes it easier to listen to music in a car, where all other+			// sources are usually ten thousand times louder than RG-adjusted music.+			// -- @spijet+			aBaselineGain = 15+		}+		aFilters := []string{+			fmt.Sprintf("volume=replaygain=track:replaygain_preamp=%ddB:replaygain_noclip=0", aBaselineGain),+			"alimiter=level=disabled",+			"asidedata=mode=delete:type=REPLAYGAIN",+		}++		// opus always forces output to 48kHz sampling rate, but we can still use upsampling+		// to increase RG and alimiter's peak limiting precision, which is desirable in some+		// cases. ffmpeg's `soxr` resampler is quite fast on x86-64: it takes around 5 seconds+		// on my Ryzen 3600 to transcode an 8-minute FLAC with 2x upsample and RG applied.+		// -- @spijet+		if profile.upsample {+			aFilters = append([]string{"aresample=96000:resampler=soxr"}, aFilters...)+		}

nit, if the order doesn't matter here this can be a bit simpler

		if profile.upsample {
			aFilters = append(aFilters, "aresample=96000:resampler=soxr")
		}
spijet

comment created time in a month

Pull request review commentsentriz/gonic

feat(encode): rework encoding profiles to use true VBR and add optional upsample support

 func fileExists(filename string) bool {  func Profiles() map[string]Profile { 	return map[string]Profile{-		"mp3":     {"mp3", 128, []string{"-c:a", "libmp3lame"}, false},-		"mp3_rg":  {"mp3", 128, []string{"-c:a", "libmp3lame"}, true},-		"opus":    {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, false},-		"opus_rg": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, true},+		"mp3":      {"mp3", 128, []string{"-c:a", "libmp3lame"}, false, false, false},+		"mp3_rg":   {"mp3", 128, []string{"-c:a", "libmp3lame"}, true, false, false},+		"opus":     {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, false, false, false},+		"opus_rg":  {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, false, false},+		"opus_car": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "on"}, true, true, true},

now with all these booleans, it's little bit hard to know what's going on with for example false, false, false

maybe we could add some field names, and use go's false bool zero-value?

		"mp3": {
			Format:        "mp3",
			Bitrate:       128,
			ffmpegOptions: []string{"-c:a", "libmp3lame"},
		},
		"mp3_rg": {
			Format:        "mp3",
			Bitrate:       128,
			ffmpegOptions: []string{"-c:a", "libmp3lame"},
			forceRG:       true,
		},
		"opus": {
			Format:        "opus",
			Bitrate:       96,
			ffmpegOptions: []string{"-c:a", "libopus", "-vbr", "on"},
		},
		"opus_rg": {
			Format:        "opus",
			Bitrate:       96,
			ffmpegOptions: []string{"-c:a", "libopus", "-vbr", "on"},
			forceRG:       true,
		},
		"opus_car": {
			Format:        "opus",
			Bitrate:       96,
			ffmpegOptions: []string{"-c:a", "libopus", "-vbr", "on"},
			forceRG:       true,
			hiGainRG:      true,
			upsample:      true,
		},
spijet

comment created time in a month

PullRequestReviewEvent

pull request commentsentriz/gonic

feat(encode): rework encoding profiles to use true VBR and add optional upsample support

yep I'd say this can be rebased now :+1:

spijet

comment created time in a month

pull request commentsentriz/gonic

Add MIME-type and content length hints to cache handlers

cool thanks! :)

spijet

comment created time in a month