Mercurial > audlegacy-plugins
annotate src/filewriter/flac.c @ 3127:8255be301249
define NEON_DEBUG for the moment
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Wed, 06 May 2009 14:06:28 -0500 |
parents | dcd8d93ba781 |
children |
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 { | |
2950
dcd8d93ba781
- mp3: adapted to lame-3.98. now filewriter writes valid TLEN.
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
2873
diff
changeset
|
57 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 olen = 0; | |
97 | |
98 flac_encoder = FLAC__stream_encoder_new(); | |
99 | |
100 FLAC__stream_encoder_set_channels(flac_encoder, input.channels); | |
101 FLAC__stream_encoder_set_sample_rate(flac_encoder, input.frequency); | |
102 FLAC__stream_encoder_init_stream(flac_encoder, flac_write_cb, flac_seek_cb, flac_tell_cb, | |
103 NULL, output_file); | |
104 | |
995
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
105 if (tuple) |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
106 { |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
107 FLAC__StreamMetadata *meta; |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
108 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
|
109 |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
110 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
|
111 |
1976
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1687
diff
changeset
|
112 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
|
113 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
|
114 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
|
115 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
|
116 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
|
117 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
|
118 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
|
119 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
|
120 |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
121 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
|
122 } |
73f5e44d20d2
[svn] - add tuple handling, but i don't think i'm doing it right...
nenolod
parents:
994
diff
changeset
|
123 |
991 | 124 return 1; |
125 } | |
126 | |
127 static void flac_write(gpointer data, gint length) | |
128 { | |
994
91f9925d88f1
[svn] - use my version for now as r2126 does not work
nenolod
parents:
993
diff
changeset
|
129 #if 1 |
991 | 130 FLAC__int32 *encbuffer[2]; |
131 short int *tmpdata = data; | |
132 int i; | |
133 | |
134 encbuffer[0] = g_new0(FLAC__int32, length / input.channels); | |
135 encbuffer[1] = g_new0(FLAC__int32, length / input.channels); | |
136 | |
137 if (input.channels == 1) | |
138 { | |
139 for (i = 0; i < (length / 2); i++) | |
140 { | |
992 | 141 encbuffer[0][i] = tmpdata[i]; |
142 encbuffer[1][i] = tmpdata[i]; | |
991 | 143 } |
144 } | |
145 else | |
146 { | |
147 for (i = 0; i < (length / 4); i++) | |
148 { | |
992 | 149 encbuffer[0][i] = tmpdata[2 * i]; |
150 encbuffer[1][i] = tmpdata[2 * i + 1]; | |
991 | 151 } |
152 } | |
153 | |
1044
b1128efde471
[svn] - get rid of all warnings gcc 4.2.0 emits with my build configuration.
yaz
parents:
1002
diff
changeset
|
154 FLAC__stream_encoder_process(flac_encoder, (const FLAC__int32 **)encbuffer, length / (input.channels * 2)); |
991 | 155 olen += length; |
156 | |
157 g_free(encbuffer[0]); | |
158 g_free(encbuffer[1]); | |
994
91f9925d88f1
[svn] - use my version for now as r2126 does not work
nenolod
parents:
993
diff
changeset
|
159 #else |
993 | 160 FLAC__int32 *encbuffer; |
994
91f9925d88f1
[svn] - use my version for now as r2126 does not work
nenolod
parents:
993
diff
changeset
|
161 gint16 *tmpdata = data; |
993 | 162 int i; |
163 | |
164 encbuffer = g_new0(FLAC__int32, length); | |
165 | |
996 | 166 for (i=0; i < length; i++) { |
993 | 167 encbuffer[i] = tmpdata[i]; |
168 } | |
169 | |
996 | 170 FLAC__stream_encoder_process_interleaved(flac_encoder, encbuffer, length); |
993 | 171 olen += length; |
172 | |
173 g_free(encbuffer); | |
994
91f9925d88f1
[svn] - use my version for now as r2126 does not work
nenolod
parents:
993
diff
changeset
|
174 #endif |
991 | 175 } |
176 | |
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
|
177 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
|
178 { |
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 //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
|
180 } |
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 |
991 | 182 static void flac_close(void) |
183 { | |
184 FLAC__stream_encoder_finish(flac_encoder); | |
185 FLAC__stream_encoder_delete(flac_encoder); | |
186 } | |
187 | |
188 static gint flac_free(void) | |
189 { | |
190 return 1000000; | |
191 } | |
192 | |
193 static gint flac_playing(void) | |
194 { | |
195 return 0; | |
196 } | |
197 | |
198 static gint flac_get_written_time(void) | |
199 { | |
200 if (input.frequency && input.channels) | |
1269
0e160bafce1c
- adapt filewriter for file:// scheme.
Yoshiki Yazawa <yaz@cc.rim.or.jp>
parents:
1044
diff
changeset
|
201 return (gint) ((olen * 1000) / (input.frequency * 2 * input.channels) + offset); |
991 | 202 |
203 return 0; | |
204 } | |
1002
ad29227009f6
[svn] ifdef filewriter/flac.c out completely if FILEWRITER_FLAC isn't defined
js
parents:
996
diff
changeset
|
205 |
ad29227009f6
[svn] ifdef filewriter/flac.c out completely if FILEWRITER_FLAC isn't defined
js
parents:
996
diff
changeset
|
206 #endif |