aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2008-10-30 17:28:05 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2008-10-30 17:28:05 +0000
commit304dc519d9d68b3861af998a997c5f2a97c9235d (patch)
tree8dec3f0d3f5b63ae97432ee9a43482c8e35fee37 /src
parentf0d2a4c14b10bffe95250242c13cde032266778f (diff)
downloadqmmp-304dc519d9d68b3861af998a997c5f2a97c9235d.tar.gz
qmmp-304dc519d9d68b3861af998a997c5f2a97c9235d.tar.bz2
qmmp-304dc519d9d68b3861af998a997c5f2a97c9235d.zip
enabled aac plugin
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@605 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src')
-rw-r--r--src/plugins/Input/CMakeLists.txt5
-rw-r--r--src/plugins/Input/Input.pro6
-rw-r--r--src/plugins/Input/aac/CMakeLists.txt75
-rw-r--r--src/plugins/Input/aac/aacfile.cpp55
-rw-r--r--src/plugins/Input/aac/aacfile.h3
-rw-r--r--src/plugins/Input/aac/decoder_aac.cpp56
-rw-r--r--src/plugins/Input/aac/decoder_aac.h2
7 files changed, 177 insertions, 25 deletions
diff --git a/src/plugins/Input/CMakeLists.txt b/src/plugins/Input/CMakeLists.txt
index 80fe7d9d0..1164598c0 100644
--- a/src/plugins/Input/CMakeLists.txt
+++ b/src/plugins/Input/CMakeLists.txt
@@ -9,6 +9,7 @@ SET(USE_MPC TRUE CACHE BOOL "enable/disable mpc plugin")
SET(USE_SNDFILE TRUE CACHE BOOL "enable/disable sndfile plugin")
SET(USE_WAVPACK TRUE CACHE BOOL "enable/disable wavpack plugin")
SET(USE_MODPLUG TRUE CACHE BOOL "enable/disable modplug plugin")
+SET(USE_AAC TRUE CACHE BOOL "enable/disable aac plugin")
SET(USE_CUE TRUE CACHE BOOL "enable/disable cue plugin")
pkg_check_modules(TAGLIB taglib)
@@ -45,6 +46,10 @@ IF(USE_MODPLUG)
add_subdirectory(modplug)
ENDIF(USE_MODPLUG)
+IF(USE_AAC)
+add_subdirectory(aac)
+ENDIF(USE_AAC)
+
IF(USE_CUE)
add_subdirectory(cue)
ENDIF(USE_CUE)
diff --git a/src/plugins/Input/Input.pro b/src/plugins/Input/Input.pro
index c4197bfaa..c15c5531c 100644
--- a/src/plugins/Input/Input.pro
+++ b/src/plugins/Input/Input.pro
@@ -31,3 +31,9 @@ contains(CONFIG, FFMPEG_PLUGIN){
message(*************************)
}
+contains(CONFIG, AAC_PLUGIN){
+ SUBDIRS += aac
+ message(**********************)
+ message(* AAC plugin enabled *)
+ message(**********************)
+}
diff --git a/src/plugins/Input/aac/CMakeLists.txt b/src/plugins/Input/aac/CMakeLists.txt
new file mode 100644
index 000000000..1da0221c8
--- /dev/null
+++ b/src/plugins/Input/aac/CMakeLists.txt
@@ -0,0 +1,75 @@
+project(libaac)
+
+INCLUDE(CheckIncludeFileCXX)
+cmake_minimum_required(VERSION 2.4.7)
+
+if(COMMAND cmake_policy)
+cmake_policy(SET CMP0003 NEW)
+endif(COMMAND cmake_policy)
+
+
+# qt plugin
+ADD_DEFINITIONS( -Wall )
+ADD_DEFINITIONS(${QT_DEFINITIONS})
+ADD_DEFINITIONS(-DQT_PLUGIN)
+ADD_DEFINITIONS(-DQT_NO_DEBUG)
+ADD_DEFINITIONS(-DQT_SHARED)
+ADD_DEFINITIONS(-DQT_THREAD)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+SET(QT_INCLUDES
+ ${QT_INCLUDES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../
+)
+
+# libqmmp
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../)
+link_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../qmmp)
+
+# libaac
+
+CHECK_INCLUDE_FILE_CXX(neaacdec.h FAAD_FOUND)
+
+include_directories(${TAGLIB_INCLUDE_DIRS})
+link_directories(${TAGLIB_LIBRARY_DIRS})
+
+SET(libaac_SRCS
+ decoder_aac.cpp
+ decoderaacfactory.cpp
+ detailsdialog.cpp
+ aacfile.cpp
+)
+
+SET(libaac_MOC_HDRS
+ decoderaacfactory.h
+ decoder_aac.h
+ detailsdialog.h
+ aacfile.h
+)
+
+#SET(libaac_RCCS translations/translations.qrc)
+
+QT4_ADD_RESOURCES(libaac_RCC_SRCS ${libaac_RCCS})
+
+QT4_WRAP_CPP(libaac_MOC_SRCS ${libaac_MOC_HDRS})
+
+# user interface
+
+
+SET(libaac_UIS
+ detailsdialog.ui
+)
+
+QT4_WRAP_UI(libaac_UIS_H ${libaac_UIS})
+# Don't forget to include output directory, otherwise
+# the UI file won't be wrapped!
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+IF(FAAD_FOUND)
+ADD_LIBRARY(aac SHARED ${libaac_SRCS} ${libaac_MOC_SRCS} ${libaac_UIS_H}
+ ${libaac_RCC_SRCS})
+add_dependencies(aac qmmp)
+target_link_libraries(aac ${QT_LIBRARIES} -lqmmp -lfaad ${TAGLIB_LDFLAGS} ${TAGLIB_CFLAGS})
+install(TARGETS aac DESTINATION ${LIB_DIR}/qmmp/Input)
+ENDIF(FAAD_FOUND)
diff --git a/src/plugins/Input/aac/aacfile.cpp b/src/plugins/Input/aac/aacfile.cpp
index 9cf3184d8..f25c31202 100644
--- a/src/plugins/Input/aac/aacfile.cpp
+++ b/src/plugins/Input/aac/aacfile.cpp
@@ -25,20 +25,62 @@
#include "aacfile.h"
#define MAX_CHANNELS 6
+#define AAC_BUFFER_SIZE 4096
static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};
AACFile::AACFile(QIODevice *i)
{
+ m_isValid = FALSE;
m_length = 0;
m_bitrate = 0;
m_input = i;
- parseADTS();
+ uchar buf[AAC_BUFFER_SIZE];
+ qint64 buf_at = i->peek((char *) buf, AAC_BUFFER_SIZE);
+
+ int tag_size = 0;
+ if (!memcmp(buf, "ID3", 3)) //TODO parse id3 tag
+ {
+ /* high bit is not used */
+ tag_size = (buf[6] << 21) | (buf[7] << 14) |
+ (buf[8] << 7) | (buf[9] << 0);
+
+ tag_size += 10;
+ if (buf_at - tag_size < 4)
+ {
+ qWarning("AACFile: invalid tag size");
+ return;
+ }
+ memmove (buf, buf + tag_size, buf_at - tag_size);
+ }
+ //try to determenate header type;
+ if (buf[0] == 0xff && ((buf[1] & 0xf6) == 0xf0))
+ {
+ qDebug("AACFile: ADTS header found");
+ if (!i->isSequential())
+ parseADTS();
+ m_isValid = TRUE;
+ }
+ else if (memcmp(buf, "ADIF", 4) == 0)
+ {
+ qDebug("AACFile: ADIF header found");
+ int skip_size = (buf[4] & 0x80) ? 9 : 0;
+ m_bitrate = ((buf[4 + skip_size] & 0x0F)<<19) |
+ (buf[5 + skip_size]<<11) |
+ (buf[6 + skip_size]<<3) |
+ (buf[7 + skip_size] & 0xE0);
+
+ if (!i->isSequential ())
+ m_length = (qint64) (((float)i->size()*8.f)/((float)m_bitrate) + 0.5f);
+ else
+ m_length = 0;
+ m_bitrate = (int)((float)m_bitrate/1000.0f + 0.5f);
+ m_isValid = TRUE;
+ }
}
AACFile::~AACFile()
-{
-}
+{}
qint64 AACFile::length()
{
@@ -52,7 +94,7 @@ quint32 AACFile::bitrate()
void AACFile::parseADTS()
{
- uchar *buf = new uchar[FAAD_MIN_STREAMSIZE*MAX_CHANNELS];
+ uchar buf[FAAD_MIN_STREAMSIZE*MAX_CHANNELS];
qint64 buf_at = 0;
int frames, frame_length;
int t_framelength = 0;
@@ -118,3 +160,8 @@ void AACFile::parseADTS()
else
m_length = 1;
}
+
+bool AACFile::isValid()
+{
+ return m_isValid;
+}
diff --git a/src/plugins/Input/aac/aacfile.h b/src/plugins/Input/aac/aacfile.h
index 2d2ca1db5..4199a3c05 100644
--- a/src/plugins/Input/aac/aacfile.h
+++ b/src/plugins/Input/aac/aacfile.h
@@ -34,13 +34,14 @@ public:
qint64 length();
quint32 bitrate();
+ bool isValid();
private:
void parseADTS();
qint64 m_length;
quint32 m_bitrate;
QIODevice *m_input;
-
+ bool m_isValid;
};
#endif
diff --git a/src/plugins/Input/aac/decoder_aac.cpp b/src/plugins/Input/aac/decoder_aac.cpp
index 114c39a18..65d91e4ed 100644
--- a/src/plugins/Input/aac/decoder_aac.cpp
+++ b/src/plugins/Input/aac/decoder_aac.cpp
@@ -153,10 +153,18 @@ bool DecoderAAC::initialize()
{
if (!input()->open(QIODevice::ReadOnly))
{
- qWarning("DecoderAAC: unable to open input.");
+ qWarning("DecoderAAC: %s", qPrintable(input()->errorString ()));
return FALSE;
}
}
+ AACFile aac_file(input());
+ if (!aac_file.isValid())
+ {
+ qWarning("DecoderAAC: unsupported AAC file");
+ return FALSE;
+ }
+ m_totalTime = aac_file.length();
+ m_bitrate = aac_file.bitrate();
if (!m_data)
m_data = new aac_data;
@@ -171,26 +179,39 @@ bool DecoderAAC::initialize()
conf->defObjectType = LC;
conf->outputFormat = FAAD_FMT_16BIT;
NeAACDecSetConfiguration(data()->handle, conf);
+
m_input_at = input()->read((char *)m_input_buf, AAC_BUFFER_SIZE);
- for (int i = 0; i < m_input_at - 1; i++)
+
+ //skip id3 tag
+ int tag_size = 0;
+ if (!memcmp(m_input_buf, "ID3", 3))
{
- if ((uchar)m_input_buf[i] == 0xff && ((uchar)m_input_buf[i+1]&0xf6) == 0xf0)
- {
- memmove (m_input_buf, m_input_buf + i, AAC_BUFFER_SIZE - i);
- m_input_at -= i;
- break;
- }
+ /* high bit is not used */
+ tag_size = (m_input_buf[6] << 21) | (m_input_buf[7] << 14) |
+ (m_input_buf[8] << 7) | (m_input_buf[9] << 0);
+
+ tag_size += 10;
+ memmove (m_input_buf, m_input_buf + tag_size, m_input_at - tag_size);
+ m_input_at -= tag_size;
+ m_input_at += input()->read((char *)(m_input_buf + m_input_at), AAC_BUFFER_SIZE - m_input_at);
}
- AACFile aac_file(input());
- m_totalTime = aac_file.length();
- m_bitrate = aac_file.bitrate();
int res = NeAACDecInit (data()->handle, (unsigned char*) m_input_buf, m_input_at, &m_freq, &m_chan);
+
+ if (res < 0)
+ {
+ qWarning("DecoderAAC: NeAACDecInit() failed");
+ return FALSE;
+ }
+ if (!m_freq || !m_chan)
+ {
+ qWarning("DecoderAAC: invalid sound parameters");
+ return FALSE;
+ }
+
memmove(m_input_buf, m_input_buf + res, m_input_at - res);
m_input_at -= res;
-
configure(m_freq, m_chan, 16);
-
m_inited = TRUE;
qDebug("DecoderAAC: initialize succes");
return TRUE;
@@ -248,8 +269,6 @@ void DecoderAAC::deinit()
void DecoderAAC::run()
{
- m_prebuf_pos = 0;
- m_prebuf_size = 0;
mutex()->lock ();
if (!m_inited)
{
@@ -263,16 +282,15 @@ void DecoderAAC::run()
mutex()->lock ();
// decode
- if (m_seekTime >= 0.0)
+ if (m_seekTime >= 0 && m_totalTime)
{
- //mpc_decoder_seek_seconds(&data()->decoder, seekTime);
input()->seek(m_seekTime * input()->size() / m_totalTime);
+ NeAACDecPostSeekReset (data()->handle, -1);
m_input_at = 0;
m_seekTime = -1.0;
}
- m_prebuf_size = aac_decode(m_prebuf2);
- m_len = m_prebuf_size;
+ m_len = aac_decode(m_prebuf2);
if (m_len > 0)
{
diff --git a/src/plugins/Input/aac/decoder_aac.h b/src/plugins/Input/aac/decoder_aac.h
index 5a1d698ea..cb7911587 100644
--- a/src/plugins/Input/aac/decoder_aac.h
+++ b/src/plugins/Input/aac/decoder_aac.h
@@ -63,7 +63,7 @@ private:
// output buffer
char *m_output_buf, *m_input_buf;
void *m_prebuf2;
- qint64 m_output_bytes, m_output_at, m_input_at, m_prebuf_pos, m_prebuf_size;
+ qint64 m_output_bytes, m_output_at, m_input_at;
unsigned int m_bks;
bool m_done, m_finish;