Mercurial > audlegacy-plugins
annotate src/filewriter/flac.c @ 2938:597857a52f7c
Automated merge with ssh://hg.atheme.org//hg/audacious-plugins
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 18 Sep 2008 08:19:56 +0300 |
parents | 31d6c44ffef2 |
children | dcd8d93ba781 |
rev | line source |
---|---|
991 | 1 /* FileWriter FLAC Plugin |
2 * Copyright (c) 2007 William Pitcock <nenolod@sacredspiral.co.uk> | |
3 * | |
4 * Partially derived from Og(g)re - Ogg-Output-Plugin: | |
5 * Copyright (c) 2002 Lars Siebold <khandha5@gmx.net> | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
2835 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
991 | 20 */ |
21 | |
22 #include "plugins.h" | |
1002
ad29227009f6
[svn] ifdef filewriter/flac.c out completely if FILEWRITER_FLAC isn't defined
js
parents:
996
diff
changeset
|
23 |
ad29227009f6
[svn] ifdef filewriter/flac.c out completely if FILEWRITER_FLAC isn't defined
js
parents:
996
diff
changeset
|
24 #ifdef FILEWRITER_FLAC |
ad29227009f6
[svn] ifdef filewriter/flac.c out completely if FILEWRITER_FLAC isn't defined
js
parents:
996
diff
changeset
|
25 |
995
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
26 #include <FLAC/all.h> |
991 | 27 #include <stdlib.h> |
28 | |
29 static gint flac_open(void); | |
30 static void flac_write(gpointer data, gint length); | |
2774
f1f7ee810de8
add metadata to stream + flush() should do a real flush at least with mp3
Andrew O. Shadoura <bugzilla@tut.by>
parents:
1978
diff
changeset
|
31 static void flac_flush(void); |
991 | 32 static void flac_close(void); |
33 static gint flac_free(void); | |
34 static gint flac_playing(void); | |
35 static gint flac_get_written_time(void); | |
36 | |
37 FileWriter flac_plugin = | |
38 { | |
39 NULL, | |
40 NULL, | |
41 flac_open, | |
42 flac_write, | |
2774
f1f7ee810de8
add metadata to stream + flush() should do a real flush at least with mp3
Andrew O. Shadoura <bugzilla@tut.by>
parents:
1978
diff
changeset
|
43 flac_flush, |
991 | 44 flac_close, |
45 flac_free, | |
46 flac_playing, | |
2873
31d6c44ffef2
most of encoder backends require GINT16_NE;
Andrew O. Shadoura <bugzilla@tut.by>
parents:
2835
diff
changeset
|
47 flac_get_written_time, |
31d6c44ffef2
most of encoder backends require GINT16_NE;
Andrew O. Shadoura <bugzilla@tut.by>
parents:
2835
diff
changeset
|
48 FMT_S16_NE |
991 | 49 }; |
50 | |
51 static FLAC__StreamEncoder *flac_encoder; | |
52 static guint64 olen = 0; | |
53 | |
54 static FLAC__StreamEncoderWriteStatus flac_write_cb(const FLAC__StreamEncoder *encoder, | |
55 const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, gpointer data) | |
56 { | |
1978 | 57 written += aud_vfs_fwrite(buffer, bytes, 1, (VFSFile *) data); |
991 | 58 |
59 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; | |
60 } | |
61 | |
62 static FLAC__StreamEncoderSeekStatus flac_seek_cb(const FLAC__StreamEncoder *encoder, | |
63 FLAC__uint64 absolute_byte_offset, gpointer data) | |
64 { | |
65 VFSFile *file = (VFSFile *) data; | |
66 | |
1978 | 67 if (aud_vfs_fseek(file, absolute_byte_offset, SEEK_SET) < 0) |
991 | 68 return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR; |
69 | |
70 return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; | |
71 } | |
72 | |
73 static FLAC__StreamEncoderTellStatus flac_tell_cb(const FLAC__StreamEncoder *encoder, | |
74 FLAC__uint64 *absolute_byte_offset, gpointer data) | |
75 { | |
76 VFSFile *file = (VFSFile *) data; | |
77 | |
1978 | 78 *absolute_byte_offset = aud_vfs_ftell(file); |
991 | 79 |
80 return FLAC__STREAM_ENCODER_TELL_STATUS_OK; | |
81 } | |
82 | |
995
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
83 #define INSERT_VORBIS_COMMENT(t, keyword) \ |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
84 if (t) \ |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
85 { \ |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
86 gchar *scratch = g_strdup_printf(keyword, t); \ |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
87 comment_entry.length = strlen(scratch); \ |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
88 comment_entry.entry = (guchar *) scratch; \ |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
89 FLAC__metadata_object_vorbiscomment_insert_comment(meta, \ |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
90 meta->data.vorbis_comment.num_comments, comment_entry, TRUE); \ |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
91 g_free(scratch); \ |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
92 } |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
93 |
991 | 94 static gint flac_open(void) |
95 { | |
96 written = 0; | |
97 olen = 0; | |
98 | |
99 flac_encoder = FLAC__stream_encoder_new(); | |
100 | |
101 FLAC__stream_encoder_set_channels(flac_encoder, input.channels); | |
102 FLAC__stream_encoder_set_sample_rate(flac_encoder, input.frequency); | |
103 FLAC__stream_encoder_init_stream(flac_encoder, flac_write_cb, flac_seek_cb, flac_tell_cb, | |
104 NULL, output_file); | |
105 | |
995
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
106 if (tuple) |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
107 { |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
108 FLAC__StreamMetadata *meta; |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
109 FLAC__StreamMetadata_VorbisComment_Entry comment_entry; |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
110 |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
111 meta = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
112 |
1976
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1687
diff
changeset
|
113 INSERT_VORBIS_COMMENT(aud_tuple_get_string(tuple, FIELD_TITLE, NULL), "title=%s"); |
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1687
diff
changeset
|
114 INSERT_VORBIS_COMMENT(aud_tuple_get_string(tuple, FIELD_ARTIST, NULL), "artist=%s"); |
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1687
diff
changeset
|
115 INSERT_VORBIS_COMMENT(aud_tuple_get_string(tuple, FIELD_ALBUM, NULL), "album=%s"); |
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1687
diff
changeset
|
116 INSERT_VORBIS_COMMENT(aud_tuple_get_string(tuple, FIELD_GENRE, NULL), "genre=%s"); |
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1687
diff
changeset
|
117 INSERT_VORBIS_COMMENT(aud_tuple_get_string(tuple, FIELD_COMMENT, NULL), "comment=%s"); |
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1687
diff
changeset
|
118 INSERT_VORBIS_COMMENT(aud_tuple_get_string(tuple, FIELD_DATE, NULL), "date=%s"); |
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1687
diff
changeset
|
119 INSERT_VORBIS_COMMENT(aud_tuple_get_int(tuple, FIELD_YEAR, NULL), "year=%d"); |
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1687
diff
changeset
|
120 INSERT_VORBIS_COMMENT(aud_tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL), "tracknumber=%d"); |
995
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
121 |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
122 FLAC__stream_encoder_set_metadata(flac_encoder, &meta, 1); |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
123 } |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
124 |
991 | 125 return 1; |
126 } | |
127 | |
128 static void flac_write(gpointer data, gint length) | |
129 { | |
994
91f9925d88f1
[svn] - use my version for now as r2126 does not work
nenolod
parents:
993
diff
changeset
|
130 #if 1 |
991 | 131 FLAC__int32 *encbuffer[2]; |
132 short int *tmpdata = data; | |
133 int i; | |
134 | |
135 encbuffer[0] = g_new0(FLAC__int32, length / input.channels); | |
136 encbuffer[1] = g_new0(FLAC__int32, length / input.channels); | |
137 | |
138 if (input.channels == 1) | |
139 { | |
140 for (i = 0; i < (length / 2); i++) | |
141 { | |
992 | 142 encbuffer[0][i] = tmpdata[i]; |
143 encbuffer[1][i] = tmpdata[i]; | |
991 | 144 } |
145 } | |
146 else | |
147 { | |
148 for (i = 0; i < (length / 4); i++) | |
149 { | |
992 | 150 encbuffer[0][i] = tmpdata[2 * i]; |
151 encbuffer[1][i] = tmpdata[2 * i + 1]; | |
991 | 152 } |
153 } | |
154 | |
1044
b1128efde471
[svn] - get rid of all warnings gcc 4.2.0 emits with my build configuration.
yaz
parents:
1002
diff
changeset
|
155 FLAC__stream_encoder_process(flac_encoder, (const FLAC__int32 **)encbuffer, length / (input.channels * 2)); |
991 | 156 olen += length; |
157 | |
158 g_free(encbuffer[0]); | |
159 g_free(encbuffer[1]); | |
994
91f9925d88f1
[svn] - use my version for now as r2126 does not work
nenolod
parents:
993
diff
changeset
|
160 #else |
993 | 161 FLAC__int32 *encbuffer; |
994
91f9925d88f1
[svn] - use my version for now as r2126 does not work
nenolod
parents:
993
diff
changeset
|
162 gint16 *tmpdata = data; |
993 | 163 int i; |
164 | |
165 encbuffer = g_new0(FLAC__int32, length); | |
166 | |
996 | 167 for (i=0; i < length; i++) { |
993 | 168 encbuffer[i] = tmpdata[i]; |
169 } | |
170 | |
996 | 171 FLAC__stream_encoder_process_interleaved(flac_encoder, encbuffer, length); |
993 | 172 olen += length; |
173 | |
174 g_free(encbuffer); | |
994
91f9925d88f1
[svn] - use my version for now as r2126 does not work
nenolod
parents:
993
diff
changeset
|
175 #endif |
991 | 176 } |
177 | |
2774
f1f7ee810de8
add metadata to stream + flush() should do a real flush at least with mp3
Andrew O. Shadoura <bugzilla@tut.by>
parents:
1978
diff
changeset
|
178 static void flac_flush(void) |
f1f7ee810de8
add metadata to stream + flush() should do a real flush at least with mp3
Andrew O. Shadoura <bugzilla@tut.by>
parents:
1978
diff
changeset
|
179 { |
f1f7ee810de8
add metadata to stream + flush() should do a real flush at least with mp3
Andrew O. Shadoura <bugzilla@tut.by>
parents:
1978
diff
changeset
|
180 //should we do something here? --AOS |
f1f7ee810de8
add metadata to stream + flush() should do a real flush at least with mp3
Andrew O. Shadoura <bugzilla@tut.by>
parents:
1978
diff
changeset
|
181 } |
f1f7ee810de8
add metadata to stream + flush() should do a real flush at least with mp3
Andrew O. Shadoura <bugzilla@tut.by>
parents:
1978
diff
changeset
|
182 |
991 | 183 static void flac_close(void) |
184 { | |
185 FLAC__stream_encoder_finish(flac_encoder); | |
186 FLAC__stream_encoder_delete(flac_encoder); | |
187 } | |
188 | |
189 static gint flac_free(void) | |
190 { | |
191 return 1000000; | |
192 } | |
193 | |
194 static gint flac_playing(void) | |
195 { | |
196 return 0; | |
197 } | |
198 | |
199 static gint flac_get_written_time(void) | |
200 { | |
201 if (input.frequency && input.channels) | |
1269
0e160bafce1c
- adapt filewriter for file:// scheme.
Yoshiki Yazawa <yaz@cc.rim.or.jp>
parents:
1044
diff
changeset
|
202 return (gint) ((olen * 1000) / (input.frequency * 2 * input.channels) + offset); |
991 | 203 |
204 return 0; | |
205 } | |
1002
ad29227009f6
[svn] ifdef filewriter/flac.c out completely if FILEWRITER_FLAC isn't defined
js
parents:
996
diff
changeset
|
206 |
ad29227009f6
[svn] ifdef filewriter/flac.c out completely if FILEWRITER_FLAC isn't defined
js
parents:
996
diff
changeset
|
207 #endif |