mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-24 06:50:20 +01:00
Added initial implement of the audacious plugin for audacious 1.4.x or higher.
There are still a few things to do such as add a configuration GUI, but these things are marked via TODO in the source files. I also added the autoconf/automake building system. To generate everything you need, run ./bootstrap in the top level directory, it will generate the configure script. Then run ./configure. It will generate Makefile.unix, so build it via make -f Makefile.unix. Everything should be setup properly, after building, execute 'make -f Makefile.unix install' to install. git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@165 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
81cde73fef
commit
4814b482fb
7
Makefile.unix.am
Normal file
7
Makefile.unix.am
Normal file
@ -0,0 +1,7 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
AM_MAKEFLAGS=-f Makefile.unix
|
||||
|
||||
SUBDIRS = src unix
|
||||
|
||||
#EXTRA_DIST = include
|
8
bootstrap
Executable file
8
bootstrap
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
aclocal
|
||||
autoheader
|
||||
automake -a
|
||||
touch README AUTHORS NEWS ChangeLog
|
||||
autoconf
|
||||
libtoolize --copy --force
|
50
configure.in
Normal file
50
configure.in
Normal file
@ -0,0 +1,50 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ(2.53)
|
||||
AC_INIT(audacious-vgmstream,1.0.0)
|
||||
AM_INIT_AUTOMAKE(audacious-vgmstream, 1.0.0)
|
||||
AM_CONFIG_HEADER(unix/config.h)
|
||||
AM_DISABLE_STATIC
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AM_PROG_CC_STDC
|
||||
AC_HEADER_STDC
|
||||
AC_PROG_INSTALL
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
AC_PATH_X
|
||||
AC_PATH_XTRA
|
||||
|
||||
PKG_CHECK_MODULES(AUDACIOUS, [audacious >= 1.4.0],,
|
||||
[AC_MSG_ERROR([Cannot find Audacious, have you installed audacious yet?])]
|
||||
)
|
||||
|
||||
dnl Check for GTK/GLib/GThread/Pango
|
||||
|
||||
PKG_CHECK_MODULES(GTK, [glib-2.0 >= 2.6.0 gtk+-2.0 >= 2.6.0 gthread-2.0 pango],
|
||||
, [AC_MSG_ERROR([Cannot find glib2/gtk2/pango])]
|
||||
)
|
||||
|
||||
CFLAGS="$CFLAGS $AUDACIOUS_CFLAGS"
|
||||
LIBS="$LIBS $AUDACIOUS_LIBS $GTK_LIBS"
|
||||
|
||||
plugindir=`pkg-config audacious --variable=plugin_dir`
|
||||
AC_SUBST(plugindir)
|
||||
|
||||
INPUT_PLUGIN_DIR="Input"
|
||||
AC_SUBST(INPUT_PLUGIN_DIR)
|
||||
|
||||
#AC_CHECK_HEADERS(regex.h,,AC_MSG_ERROR(regex.h missing))
|
||||
#AC_CHECK_FUNCS(regcomp regexec regfree)
|
||||
|
||||
AC_PATH_X
|
||||
AC_PATH_XTRA
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile.unix
|
||||
src/Makefile.unix
|
||||
src/coding/Makefile.unix
|
||||
src/layout/Makefile.unix
|
||||
src/meta/Makefile.unix
|
||||
unix/Makefile.unix
|
||||
])
|
11
src/Makefile.unix.am
Normal file
11
src/Makefile.unix.am
Normal file
@ -0,0 +1,11 @@
|
||||
noinst_LTLIBRARIES = libvgmstream.la
|
||||
|
||||
AM_CFLAGS = -Wall @CFLAGS@ -I$(top_builddir) -I$(top_srcdir)
|
||||
AM_MAKEFLAGS=-f Makefile.unix
|
||||
|
||||
libvgmstream_la_LDFLAGS = coding/libcoding.la layout/liblayout.la meta/libmeta.la
|
||||
libvgmstream_la_SOURCES = vgmstream.c util.c streamfile.c
|
||||
|
||||
SUBDIRS = coding layout meta
|
||||
|
||||
EXTRA_DIST = pstdint.h streamfile.h streamtypes.h util.h vgmstream.h
|
9
src/coding/Makefile.unix.am
Normal file
9
src/coding/Makefile.unix.am
Normal file
@ -0,0 +1,9 @@
|
||||
noinst_LTLIBRARIES = libcoding.la
|
||||
|
||||
AM_CFLAGS = -Wall @CFLAGS@ -I$(top_builddir) -I$(top_srcdir)
|
||||
AM_MAKEFLAGS=-f Makefile.unix
|
||||
|
||||
libcoding_la_LDFLAGS =
|
||||
libcoding_la_SOURCES = adx_decoder.c g721_decoder.c ima_decoder.c ngc_afc_decoder.c ngc_dsp_decoder.c ngc_dtk_decoder.c pcm_decoder.c psx_decoder.c xa_decoder.c
|
||||
|
||||
EXTRA_DIST = coding.h g72x_state.h
|
9
src/layout/Makefile.unix.am
Normal file
9
src/layout/Makefile.unix.am
Normal file
@ -0,0 +1,9 @@
|
||||
noinst_LTLIBRARIES = liblayout.la
|
||||
|
||||
AM_CFLAGS = -Wall @CFLAGS@ -I$(top_builddir) -I$(top_srcdir)
|
||||
AM_MAKEFLAGS=-f Makefile.unix
|
||||
|
||||
liblayout_la_LDFLAGS =
|
||||
liblayout_la_SOURCES = ast_blocked.c blocked.c halpst_blocked.c interleave.c nolayout.c xa_blocked.c
|
||||
|
||||
EXTRA_DIST = layout.h
|
9
src/meta/Makefile.unix.am
Normal file
9
src/meta/Makefile.unix.am
Normal file
@ -0,0 +1,9 @@
|
||||
noinst_LTLIBRARIES = libmeta.la
|
||||
|
||||
AM_CFLAGS = -Wall @CFLAGS@ -I$(top_builddir) -I$(top_srcdir)
|
||||
AM_MAKEFLAGS=-f Makefile.unix
|
||||
|
||||
libmeta_la_LDFLAGS =
|
||||
libmeta_la_SOURCES = Cstr.c adx_header.c afc_header.c agsc.c ast.c brstm.c gcsw.c halpst.c nds_strm.c ngc_adpdtk.c ngc_dsp_std.c ps2_ads.c ps2_exst.c ps2_int.c ps2_mib.c ps2_mic.c ps2_npsf.c ps2_rxw.c ps2_svag.c ps2_vag.c psx_cdxa.c raw.c rs03.c rsf.c rwsd.c
|
||||
|
||||
EXTRA_DIST = meta.h
|
@ -526,12 +526,12 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
|
||||
if (vgmstream->layout_type == layout_interleave || vgmstream->layout_type == layout_interleave_shortblock) {
|
||||
snprintf(temp,TEMPSIZE,"interleave: %#x bytes\n",
|
||||
vgmstream->interleave_block_size);
|
||||
(int32_t)vgmstream->interleave_block_size);
|
||||
concatn(length,desc,temp);
|
||||
|
||||
if (vgmstream->layout_type == layout_interleave_shortblock) {
|
||||
snprintf(temp,TEMPSIZE,"last block interleave: %#x bytes\n",
|
||||
vgmstream->interleave_smallblock_size);
|
||||
(int32_t)vgmstream->interleave_smallblock_size);
|
||||
concatn(length,desc,temp);
|
||||
}
|
||||
}
|
||||
|
10
unix/Makefile.unix.am
Normal file
10
unix/Makefile.unix.am
Normal file
@ -0,0 +1,10 @@
|
||||
lib_LTLIBRARIES = libvgmstream.la
|
||||
|
||||
libdir = @plugindir@/@INPUT_PLUGIN_DIR@
|
||||
|
||||
AM_MAKEFLAGS=-f Makefile.unix
|
||||
AM_CFLAGS = -Wall @CFLAGS@ -I$(top_builddir) -I$(top_srcdir) -I$(top_builddir)/in_cube @GTK_CFLAGS@
|
||||
AM_LIBS =
|
||||
|
||||
libvgmstream_la_LDFLAGS = -no-undefined -module -avoid-version -export-symbols-regex get_plugin_info ../src/libvgmstream.la
|
||||
libvgmstream_la_SOURCES = main.c data.c gui.c
|
59
unix/config.h
Normal file
59
unix/config.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* unix/config.h. Generated from config.h.in by configure. */
|
||||
/* unix/config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "audacious-vgmstream"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "audacious-vgmstream"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "audacious-vgmstream 1.0.0"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "audacious-vgmstream"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.0.0"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.0.0"
|
||||
|
||||
/* Define to 1 if the X Window System is missing or not being used. */
|
||||
/* #undef X_DISPLAY_MISSING */
|
69
unix/data.c
Normal file
69
unix/data.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include <audacious/util.h>
|
||||
|
||||
void vgmstream_init();
|
||||
void vgmstream_about();
|
||||
void vgmstream_configure();
|
||||
void vgmstream_destroy();
|
||||
gboolean vgmstream_is_our_file(gchar *pFile);
|
||||
void vgmstream_play(InputPlayback *context);
|
||||
void vgmstream_stop(InputPlayback *context);
|
||||
void vgmstream_pause(InputPlayback *context,gshort paused);
|
||||
void vgmstream_seek(InputPlayback *context,gint time);
|
||||
int vgmstream_get_time(InputPlayback *context);
|
||||
void vgmstream_get_song_info(gchar *pFile,gchar **title,gint *length);
|
||||
void vgmstream_mseek(InputPlayback *context,gulong ms);
|
||||
void vgmstream_file_info_box(gchar *pFile);
|
||||
|
||||
gchar *vgmstream_exts [] = {
|
||||
"adx",
|
||||
"afc",
|
||||
"agsc",
|
||||
"ast",
|
||||
"brstm",
|
||||
"hps",
|
||||
"strm",
|
||||
"adp",
|
||||
"rsf",
|
||||
"dsp",
|
||||
"gcw",
|
||||
"ads",
|
||||
"ss2",
|
||||
"npsf",
|
||||
"rwsd",
|
||||
"xa",
|
||||
"rxw",
|
||||
"int",
|
||||
"sts",
|
||||
"svag",
|
||||
"mib",
|
||||
"mi4",
|
||||
"mpdsp",
|
||||
"mic",
|
||||
"gcm",
|
||||
"mss",
|
||||
"raw",
|
||||
"vag",
|
||||
/* terminator */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
InputPlugin vgmstream_iplug = {
|
||||
.description = "VGMStream Decoder",
|
||||
.init = vgmstream_init,
|
||||
.about = vgmstream_about,
|
||||
.configure = vgmstream_configure,
|
||||
.cleanup = vgmstream_destroy,
|
||||
.is_our_file = vgmstream_is_our_file,
|
||||
.play_file = vgmstream_play,
|
||||
.stop = vgmstream_stop,
|
||||
.pause = vgmstream_pause,
|
||||
.seek = vgmstream_seek,
|
||||
.get_time = vgmstream_get_time,
|
||||
.get_song_info = vgmstream_get_song_info,
|
||||
.vfs_extensions = vgmstream_exts,
|
||||
.mseek = vgmstream_mseek,
|
||||
.file_info_box = vgmstream_file_info_box,
|
||||
};
|
||||
|
||||
|
31
unix/gui.c
Normal file
31
unix/gui.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <audacious/util.h>
|
||||
#include <audacious/configdb.h>
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "gui.h"
|
||||
#include "version.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static GtkWidget *about_box;
|
||||
|
||||
void vgmstream_gui_about()
|
||||
{
|
||||
if (about_box)
|
||||
{
|
||||
gdk_window_raise(about_box->window);
|
||||
return;
|
||||
}
|
||||
|
||||
about_box = audacious_info_dialog(
|
||||
(gchar *) "About VGMStream Decoder",
|
||||
(gchar *) "[ VGMStream Decoder ]\n\n"
|
||||
"audacious-vgmstream version: " AUDACIOUSVGMSTREAM_VERSION "\n\n"
|
||||
"audacious-vgmstream written by Todd Jeffreys (http://voidpointer.org/)\n"
|
||||
"vgmstream written by hcs (http://www.sf.net/projects/vgmstream)",
|
||||
(gchar *) "OK",
|
||||
FALSE, NULL, NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(about_box), "destroy",
|
||||
GTK_SIGNAL_FUNC(gtk_widget_destroyed), &about_box);
|
||||
|
||||
}
|
6
unix/gui.h
Normal file
6
unix/gui.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __GUI__
|
||||
#define __GUI__
|
||||
|
||||
void vgmstream_gui_about();
|
||||
|
||||
#endif
|
372
unix/main.c
Normal file
372
unix/main.c
Normal file
@ -0,0 +1,372 @@
|
||||
#include <audacious/util.h>
|
||||
#include <audacious/configdb.h>
|
||||
#include <audacious/plugin.h>
|
||||
#include <audacious/output.h>
|
||||
#include <audacious/i18n.h>
|
||||
#include <audacious/strings.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include "version.h"
|
||||
#include "../src/vgmstream.h"
|
||||
#include "gui.h"
|
||||
|
||||
#define TM_QUIT 0
|
||||
#define TM_PLAY 1
|
||||
#define TM_SEEK 2
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
extern InputPlugin vgmstream_iplug;
|
||||
//static CDecoder decoder;
|
||||
static volatile long decode_seek;
|
||||
static GThread *decode_thread;
|
||||
static gint stream_length_samples;
|
||||
static gint loop_count = 1;
|
||||
static gint fade_seconds = 0;
|
||||
static gint fade_delay_seconds = 0;
|
||||
static gint decode_pos_samples = 0;
|
||||
static VGMSTREAM *vgmstream = NULL;
|
||||
static gchar strPlaying[260];
|
||||
static InputPlugin *vgmstream_iplist[] = { &vgmstream_iplug, NULL };
|
||||
|
||||
/*
|
||||
static gint get_ms_position()
|
||||
{
|
||||
if (vgmstream)
|
||||
{
|
||||
return (decode_pos_samples * 1000) / vgmstream->sample_rate;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/* TODO -
|
||||
|
||||
Rewrite vgmstream/STREAMFILE so that you can open a VGMSTREAM* by providing
|
||||
a custom implementation of STREAMFILE. Audacious wants you to use the
|
||||
VFS functions to do I/O, but VGMSTREAM only supports fopen/fread/etc.
|
||||
*/
|
||||
|
||||
/* Here's a function to convert file://<whatever> to the actual path */
|
||||
static void get_file_name(char *buffer,const char *pfile)
|
||||
{
|
||||
/* unconvert from file:// to regular path */
|
||||
gchar *unescaped = g_uri_unescape_string(pfile,NULL);
|
||||
if (strncmp(unescaped,"file://",7) == 0)
|
||||
{
|
||||
strcpy(buffer,unescaped+7);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(buffer,unescaped);
|
||||
}
|
||||
g_free(unescaped);
|
||||
}
|
||||
|
||||
void vgmstream_mseek(InputPlayback *data,gulong ms);
|
||||
|
||||
#define CLOSE_STREAM() do { \
|
||||
if (vgmstream) close_vgmstream(vgmstream); \
|
||||
vgmstream = NULL; } while (0)
|
||||
|
||||
SIMPLE_INPUT_PLUGIN(vgmstream,vgmstream_iplist);
|
||||
|
||||
#define DS_EXIT -2
|
||||
|
||||
void* vgmstream_play_loop(InputPlayback *playback)
|
||||
{
|
||||
int16_t buffer[576*2];
|
||||
long l;
|
||||
gint seek_needed_samples;
|
||||
gint samples_to_do;
|
||||
decode_seek = -1;
|
||||
playback->playing = 1;
|
||||
playback->eof = 0;
|
||||
|
||||
decode_pos_samples = 0;
|
||||
|
||||
while (playback->playing)
|
||||
{
|
||||
// ******************************************
|
||||
// Seeking
|
||||
// ******************************************
|
||||
// check thread flags, not my favorite method
|
||||
if (decode_seek == DS_EXIT)
|
||||
{
|
||||
goto exit_thread;
|
||||
}
|
||||
else if (decode_seek >= 0)
|
||||
{
|
||||
/* compute from ms to samples */
|
||||
seek_needed_samples = (long long)decode_seek * vgmstream->sample_rate / 1000L;
|
||||
if (seek_needed_samples < decode_pos_samples)
|
||||
{
|
||||
/* go back in time, reopen file */
|
||||
CLOSE_STREAM();
|
||||
decode_pos_samples = 0;
|
||||
vgmstream = init_vgmstream(strPlaying);
|
||||
if (vgmstream)
|
||||
{
|
||||
samples_to_do = seek_needed_samples;
|
||||
}
|
||||
else
|
||||
{
|
||||
samples_to_do = -1;
|
||||
// trigger eof
|
||||
playback->eof = 1;
|
||||
}
|
||||
}
|
||||
else if (decode_pos_samples < seek_needed_samples)
|
||||
{
|
||||
/* go forward in time */
|
||||
samples_to_do = seek_needed_samples - decode_pos_samples;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* seek to where we are, how convenient */
|
||||
samples_to_do = -1;
|
||||
}
|
||||
/* do the actual seeking */
|
||||
if (samples_to_do >= 0)
|
||||
{
|
||||
while (samples_to_do > 0)
|
||||
{
|
||||
l = min(576,samples_to_do);
|
||||
render_vgmstream(buffer,l,vgmstream);
|
||||
samples_to_do -= l;
|
||||
decode_pos_samples += l;
|
||||
}
|
||||
playback->output->flush(decode_seek);
|
||||
// reset eof flag
|
||||
playback->eof = 0;
|
||||
}
|
||||
// reset decode_seek
|
||||
decode_seek = -1;
|
||||
}
|
||||
|
||||
// ******************************************
|
||||
// Playback
|
||||
// ******************************************
|
||||
if (!playback->eof)
|
||||
{
|
||||
// read data and pass onward
|
||||
samples_to_do = min(576,stream_length_samples - (decode_pos_samples + 576));
|
||||
l = (samples_to_do * vgmstream->channels*2);
|
||||
if (!l)
|
||||
{
|
||||
playback->eof = 1;
|
||||
// will trigger on next run through
|
||||
}
|
||||
else
|
||||
{
|
||||
// ok we read stuff , pass it on
|
||||
render_vgmstream(buffer,samples_to_do,vgmstream);
|
||||
/* TODO fading */
|
||||
playback->pass_audio(playback,FMT_S16_LE,vgmstream->channels , l , buffer , &playback->playing );
|
||||
|
||||
decode_pos_samples += samples_to_do;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// at EOF
|
||||
playback->output->buffer_free();
|
||||
playback->output->buffer_free();
|
||||
while (playback->output->buffer_playing())
|
||||
g_usleep(10000);
|
||||
playback->playing = 0;
|
||||
// this effectively ends the loop
|
||||
}
|
||||
}
|
||||
exit_thread:
|
||||
decode_seek = -1;
|
||||
playback->playing = 0;
|
||||
decode_pos_samples = 0;
|
||||
CLOSE_STREAM();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vgmstream_about()
|
||||
{
|
||||
vgmstream_gui_about();
|
||||
}
|
||||
|
||||
void vgmstream_configure()
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void vgmstream_init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void vgmstream_destroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
gboolean vgmstream_is_our_file(char *pFile)
|
||||
{
|
||||
char strFile[260];
|
||||
const char *pExt;
|
||||
gchar **exts;
|
||||
VGMSTREAM *stream;
|
||||
|
||||
if (!pFile)
|
||||
return FALSE;
|
||||
|
||||
/* get extension */
|
||||
pExt = strrchr(pFile,'.');
|
||||
if (!pExt)
|
||||
return FALSE;
|
||||
/* skip past period */
|
||||
++pExt;
|
||||
|
||||
get_file_name(strFile,pFile);
|
||||
|
||||
for (exts = vgmstream_iplug.vfs_extensions;*exts;++exts)
|
||||
{
|
||||
if (strcasecmp(pExt,*exts) == 0)
|
||||
{
|
||||
if ((stream = init_vgmstream(strFile)))
|
||||
{
|
||||
close_vgmstream(stream);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void vgmstream_mseek(InputPlayback *data,gulong ms)
|
||||
{
|
||||
if (vgmstream)
|
||||
{
|
||||
decode_seek = ms;
|
||||
data->eof = 0;
|
||||
|
||||
while (decode_seek != -1)
|
||||
g_usleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
void vgmstream_play(InputPlayback *context)
|
||||
{
|
||||
// this is now called in a new thread context
|
||||
char title[260];
|
||||
|
||||
get_file_name(title,context->filename);
|
||||
|
||||
vgmstream = init_vgmstream(title);
|
||||
if (!vgmstream || vgmstream->channels <= 0 || vgmstream->channels > 2)
|
||||
{
|
||||
CLOSE_STREAM();
|
||||
return;
|
||||
}
|
||||
// open the audio device
|
||||
if (context->output->open_audio(FMT_S16_LE,vgmstream->sample_rate,vgmstream->channels) == 0)
|
||||
{
|
||||
CLOSE_STREAM();
|
||||
return;
|
||||
}
|
||||
/* copy file name */
|
||||
strcpy(strPlaying,title);
|
||||
// set the info
|
||||
stream_length_samples = get_vgmstream_play_samples(loop_count,fade_seconds,fade_delay_seconds,vgmstream);
|
||||
gint ms = (stream_length_samples * 1000LL) / vgmstream->sample_rate;
|
||||
gint rate = vgmstream->sample_rate * 2 * vgmstream->channels;
|
||||
context->set_params(context,title,
|
||||
/* length */ ms,
|
||||
/* rate */rate,
|
||||
/* freq */vgmstream->sample_rate,
|
||||
/* n channels */vgmstream->channels);
|
||||
|
||||
decode_thread = g_thread_self();
|
||||
context->set_pb_ready(context);
|
||||
vgmstream_play_loop(context);
|
||||
}
|
||||
|
||||
void vgmstream_stop(InputPlayback *context)
|
||||
{
|
||||
if (vgmstream)
|
||||
{
|
||||
// kill thread
|
||||
decode_seek = DS_EXIT;
|
||||
// wait for it to die
|
||||
g_thread_join(decode_thread);
|
||||
// close audio output
|
||||
}
|
||||
context->output->close_audio();
|
||||
// cleanup
|
||||
CLOSE_STREAM();
|
||||
}
|
||||
|
||||
void vgmstream_pause(InputPlayback *context,gshort paused)
|
||||
{
|
||||
context->output->pause(paused);
|
||||
}
|
||||
|
||||
void vgmstream_seek(InputPlayback *context,gint time)
|
||||
{
|
||||
vgmstream_mseek(context,time * 1000);
|
||||
}
|
||||
|
||||
int vgmstream_get_time(InputPlayback *context)
|
||||
{
|
||||
if (!vgmstream)
|
||||
return -2;
|
||||
|
||||
if (!context->playing ||
|
||||
(context->eof && !context->output->buffer_playing()))
|
||||
return -1;
|
||||
|
||||
return context->output->output_time();
|
||||
//return get_ms_position();
|
||||
}
|
||||
|
||||
void vgmstream_get_song_info(gchar *pFile,gchar **title,gint *length)
|
||||
{
|
||||
char strTitle[260];
|
||||
VGMSTREAM *infostream;
|
||||
|
||||
get_file_name(strTitle,pFile);
|
||||
|
||||
*title = g_strdup(strTitle);
|
||||
|
||||
if ((infostream = init_vgmstream(strTitle)))
|
||||
{
|
||||
*length = get_vgmstream_play_samples(loop_count,fade_seconds,fade_delay_seconds,infostream) * 1000LL / infostream->sample_rate;
|
||||
close_vgmstream(infostream);
|
||||
}
|
||||
else
|
||||
{
|
||||
*length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void vgmstream_file_info_box(gchar *pFile)
|
||||
{
|
||||
char msg[512];
|
||||
char strTitle[260];
|
||||
VGMSTREAM *stream;
|
||||
|
||||
get_file_name(strTitle,pFile);
|
||||
|
||||
if ((stream = init_vgmstream(strTitle)))
|
||||
{
|
||||
gint sls = get_vgmstream_play_samples(loop_count,fade_seconds,fade_delay_seconds,stream);
|
||||
gint ms = (sls * 1000LL) / stream->sample_rate;
|
||||
gint rate = stream->sample_rate * 2 * stream->channels;
|
||||
|
||||
sprintf(msg,"%s\nSample rate: %d\nStereo: %s\nTotal samples: %d\nBits per second: %d\nLength: %f seconds",strTitle,stream->sample_rate,(stream->channels >= 2) ? "yes" : "no",sls,rate,(double)ms / 1000.0);
|
||||
|
||||
close_vgmstream(stream);
|
||||
|
||||
audacious_info_dialog("File information",msg,"OK",FALSE,NULL,NULL);
|
||||
}
|
||||
}
|
6
unix/version.h
Normal file
6
unix/version.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __VERSION_H__
|
||||
#define __VERSION_H__
|
||||
|
||||
#define AUDACIOUSVGMSTREAM_VERSION "1.0.0"
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user