This repository has been archived by the owner on Jan 5, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmp3.lisp
50 lines (42 loc) · 1.8 KB
/
mp3.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
(in-package #:org.shirakumo.fraf.soloud)
(defclass mp3-source (virtual-source)
((file :initform NIL :accessor file)))
(defmethod load-file ((source mp3-source) file)
(let ((file (cl-mpg123:make-file
file
:buffer-size (* 4 1024)
:accepted-format (list (round (base-samplerate source)) :stereo :float))))
(cl-mpg123:connect file)
(cl-mpg123:scan file)
(setf (channels source) 2)
(setf (file source) file)))
(defmethod get-audio ((source mp3-source) dst samples)
(let* ((bytes (* samples 4 2))
(src (cl-mpg123:buffer (file source)))
(read (cl-mpg123:read-directly (file source) src bytes))
(read-samples (/ read 4 2)))
;; SoLoud wants L{n}R{n}, MPG123 gives (LR){n}. Need to re-encode.
(loop for i from 0 below read-samples
for k = (* i 2)
do (setf (cffi:mem-aref dst :float i) (cffi:mem-aref src :float k))
(setf (cffi:mem-aref dst :float (+ samples i)) (cffi:mem-aref src :float (1+ k))))
(when (< read bytes)
(handler-bind ((error #'invoke-debugger))
(cond ((looping-p source)
(rewind source)
(get-audio source (cffi:inc-pointer dst read) (/ (- bytes read) 4 2)))
(T
(loop for i from read-samples below samples
do (setf (cffi:mem-aref dst :float i) 0.0s0))))))))
(defmethod has-ended ((source mp3-source))
(unless (looping-p source)
(<= (cl-mpg123:sample-count (file source))
(cl-mpg123:sample-position (file source)))))
(defmethod seek-to ((source mp3-source) time scratch size)
;; I don't actually know what these arguments are.
)
(defmethod rewind ((source mp3-source))
(cl-mpg123:seek (file source) 0)
0)
(defmethod get-info ((source mp3-source) info-key)
0.0)