changeset 986:5523559a1eac trunk

[svn] - add Vorbis output mode - change "Output file extension" to "Output file format" - link against -lvorbisenc, this will probably want to be adjusted before we make a release on a 1.4 branch
author nenolod
date Mon, 30 Apr 2007 21:18:44 -0700
parents 029056fb9f9d
children 8f432e790cfb
files ChangeLog src/filewriter/Makefile src/filewriter/filewriter.c src/filewriter/plugins.h src/filewriter/vorbis.c
diffstat 5 files changed, 222 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Apr 30 20:24:34 2007 -0700
+++ b/ChangeLog	Mon Apr 30 21:18:44 2007 -0700
@@ -1,3 +1,13 @@
+2007-05-01 03:24:34 +0000  Yoshiki Yazawa <yaz@cc.rim.or.jp>
+  revision [2110]
+  - rename titles of configure windows.
+  - change packing order of OK and Cancel button in MP3 configuration window. now these buttons use stock icons.
+  
+  trunk/src/filewriter/filewriter.c |    2 +-
+  trunk/src/filewriter/mp3.c        |   20 ++++++++++----------
+  2 files changed, 11 insertions(+), 11 deletions(-)
+
+
 2007-04-30 21:16:32 +0000  Michael Farber <01mf02@gmail.com>
   revision [2108]
   - We got a new plugin, captain!
--- a/src/filewriter/Makefile	Mon Apr 30 20:24:34 2007 -0700
+++ b/src/filewriter/Makefile	Mon Apr 30 21:18:44 2007 -0700
@@ -5,8 +5,8 @@
 
 LIBDIR = $(plugindir)/$(OUTPUT_PLUGIN_DIR)
 
-LIBADD = $(GTK_LIBS) -lmp3lame
-SOURCES = filewriter.c wav.c mp3.c
+LIBADD = $(GTK_LIBS) -lmp3lame -lvorbisenc
+SOURCES = filewriter.c wav.c mp3.c vorbis.c
 
 OBJECTS = ${SOURCES:.c=.o}
 
--- a/src/filewriter/filewriter.c	Mon Apr 30 20:24:34 2007 -0700
+++ b/src/filewriter/filewriter.c	Mon Apr 30 21:18:44 2007 -0700
@@ -28,9 +28,9 @@
 static GtkWidget *configure_bbox, *configure_ok, *configure_cancel;
 
 static GtkWidget *fileext_hbox, *fileext_label, *fileext_combo, *plugin_button;
-enum fileext_t { WAV = 0, MP3, FILEEXT_MAX } ;
+enum fileext_t { WAV = 0, MP3, VORBIS, FILEEXT_MAX } ;
 static gint fileext = WAV;
-static gchar *fileext_str[] = { "wav", "mp3" } ;
+static gchar *fileext_str[] = { "wav", "mp3", "ogg" } ;
 static FileWriter plugin;
 
 static GtkWidget *saveplace_hbox, *saveplace;
@@ -102,6 +102,8 @@
         plugin = wav_plugin;
     if (fileext == MP3)
         plugin = mp3_plugin;
+    if (fileext == VORBIS)
+        plugin = vorbis_plugin;
 }
 
 static void file_init(void)
@@ -485,12 +487,13 @@
         fileext_hbox = gtk_hbox_new(FALSE, 5);
         gtk_box_pack_start(GTK_BOX(configure_vbox), fileext_hbox, FALSE, FALSE, 0);
 
-        fileext_label = gtk_label_new(_("Output file extension:"));
+        fileext_label = gtk_label_new(_("Output file format:"));
         gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_label, FALSE, FALSE, 0);
 
         fileext_combo = gtk_combo_box_new_text();
         gtk_combo_box_append_text(GTK_COMBO_BOX(fileext_combo), "WAV");
         gtk_combo_box_append_text(GTK_COMBO_BOX(fileext_combo), "MP3");
+        gtk_combo_box_append_text(GTK_COMBO_BOX(fileext_combo), "Vorbis");
         gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_combo, FALSE, FALSE, 0);
         gtk_combo_box_set_active(GTK_COMBO_BOX(fileext_combo), fileext);
         g_signal_connect(G_OBJECT(fileext_combo), "changed", G_CALLBACK(fileext_cb), NULL);
--- a/src/filewriter/plugins.h	Mon Apr 30 20:24:34 2007 -0700
+++ b/src/filewriter/plugins.h	Mon Apr 30 21:18:44 2007 -0700
@@ -25,6 +25,6 @@
 
 #include "filewriter.h"
 
-extern FileWriter wav_plugin, mp3_plugin;
+extern FileWriter wav_plugin, mp3_plugin, vorbis_plugin;
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/filewriter/vorbis.c	Mon Apr 30 21:18:44 2007 -0700
@@ -0,0 +1,203 @@
+/*  FileWriter Vorbis Plugin
+ *  Copyright (c) 2007 William Pitcock <nenolod@sacredspiral.co.uk>
+ *
+ *  Partially derived from Og(g)re - Ogg-Output-Plugin:
+ *  Copyright (c) 2002 Lars Siebold <khandha5@gmx.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "plugins.h"
+#include <vorbis/vorbisenc.h>
+#include <stdlib.h>
+
+static void vorbis_init(void);
+static gint vorbis_open(void);
+static void vorbis_write(gpointer data, gint length);
+static void vorbis_close(void);
+static gint vorbis_free(void);
+static gint vorbis_playing(void);
+static gint vorbis_get_written_time(void);
+
+FileWriter vorbis_plugin =
+{
+    vorbis_init,
+    NULL,
+    vorbis_open,
+    vorbis_write,
+    vorbis_close,
+    vorbis_free,
+    vorbis_playing,
+    vorbis_get_written_time
+};
+
+static float v_base_quality = 0.3;
+
+static ogg_stream_state os;
+static ogg_page og;
+static ogg_packet op;
+
+static vorbis_dsp_state vd;
+static vorbis_block vb;
+static vorbis_info vi;
+static vorbis_comment vc;
+
+static float **encbuffer;
+static guint64 olen = 0;
+
+static void vorbis_init(void)
+{
+    ConfigDb *db = bmp_cfg_db_open();
+
+    bmp_cfg_db_get_float(db, "filewriter_vorbis", "base_quality", &v_base_quality);
+
+    bmp_cfg_db_close(db);
+}
+
+static gint vorbis_open(void)
+{
+    gint result;
+    ogg_packet header;
+    ogg_packet header_comm;
+    ogg_packet header_code;
+
+    vorbis_init();
+
+    written = 0;
+    olen = 0;
+
+    vorbis_info_init(&vi);
+    vorbis_comment_init(&vc);
+
+    if (tuple)
+    {
+        vorbis_comment_add_tag(&vc, "title", tuple->track_name);
+        vorbis_comment_add_tag(&vc, "artist", tuple->performer);
+        vorbis_comment_add_tag(&vc, "album", tuple->album_name);
+        vorbis_comment_add_tag(&vc, "genre", tuple->genre);
+    }
+
+    if ((result = vorbis_encode_init_vbr(&vi, (long)input.channels, (long)input.frequency, v_base_quality)) != 0)
+    {
+        vorbis_info_clear(&vi);
+        return 0;
+    }
+
+    vorbis_analysis_init(&vd, &vi);
+    vorbis_block_init(&vd, &vb);
+
+    srand(time(NULL));
+    ogg_stream_init(&os, rand());
+
+    vorbis_analysis_headerout(&vd, &vc, &header, &header_comm, &header_code);
+
+    ogg_stream_packetin(&os, &header);
+    ogg_stream_packetin(&os, &header_comm);
+    ogg_stream_packetin(&os, &header_code);
+
+    while((result = ogg_stream_flush(&os, &og)))
+    {
+        if (result == 0)
+            break;
+
+        written += vfs_fwrite(og.header, 1, og.header_len, output_file);
+        written += vfs_fwrite(og.body, 1, og.body_len, output_file);
+    }
+
+    return 1;
+}
+
+static void vorbis_write(gpointer data, gint length)
+{
+    int i;
+    int result;
+    short int *tmpdata;
+
+    /* ask vorbisenc for a buffer to fill with pcm data */
+    encbuffer = vorbis_analysis_buffer(&vd, length);
+    tmpdata = data;
+
+    /*
+     * deinterleave the audio signal, 32768.0 is the highest peak level allowed
+     * in a 16-bit PCM signal.
+     */
+    if (input.channels == 1)
+    {
+        for (i = 0; i < (length / 2); i++)
+        {
+            encbuffer[0][i] = tmpdata[i] / 32768.0;
+            encbuffer[1][i] = tmpdata[i] / 32768.0;
+        }
+    }
+    else
+    {
+        for (i = 0; i < (length / 4); i++)
+        {
+            encbuffer[0][i] = tmpdata[2 * i] / 32768.0;
+            encbuffer[1][i] = tmpdata[2 * i + 1] / 32768.0;
+        }
+    }
+
+    vorbis_analysis_wrote(&vd, i);
+
+    while(vorbis_analysis_blockout(&vd, &vb) == 1)
+    {
+        vorbis_analysis(&vb, &op);
+        vorbis_bitrate_addblock(&vb);
+
+        while (vorbis_bitrate_flushpacket(&vd, &op))
+        {
+            ogg_stream_packetin(&os, &op);
+
+            while ((result = ogg_stream_pageout(&os, &og)))
+            {
+                if (result == 0)
+                    break;
+
+                written += vfs_fwrite(og.header, 1, og.header_len, output_file);
+                written += vfs_fwrite(og.body, 1, og.body_len, output_file);
+            }
+        }
+    }
+
+    olen += length;
+}
+
+static void vorbis_close(void)
+{
+    ogg_stream_clear(&os);
+
+    vorbis_block_clear(&vb);
+    vorbis_dsp_clear(&vd);
+    vorbis_info_clear(&vi);
+}
+
+static gint vorbis_free(void)
+{
+    return 1000000;
+}
+
+static gint vorbis_playing(void)
+{
+    return 0;
+}
+
+static gint vorbis_get_written_time(void)
+{
+    if (input.frequency && input.channels)
+        return (gint) ((olen * 1000) / (input.frequency * 2 * input.channels));
+
+    return 0;
+}