diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2008-10-30 17:28:05 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2008-10-30 17:28:05 +0000 |
| commit | 304dc519d9d68b3861af998a997c5f2a97c9235d (patch) | |
| tree | 8dec3f0d3f5b63ae97432ee9a43482c8e35fee37 | |
| parent | f0d2a4c14b10bffe95250242c13cde032266778f (diff) | |
| download | qmmp-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
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | qmmp.pri | 1 | ||||
| -rw-r--r-- | src/plugins/Input/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | src/plugins/Input/Input.pro | 6 | ||||
| -rw-r--r-- | src/plugins/Input/aac/CMakeLists.txt | 75 | ||||
| -rw-r--r-- | src/plugins/Input/aac/aacfile.cpp | 55 | ||||
| -rw-r--r-- | src/plugins/Input/aac/aacfile.h | 3 | ||||
| -rw-r--r-- | src/plugins/Input/aac/decoder_aac.cpp | 56 | ||||
| -rw-r--r-- | src/plugins/Input/aac/decoder_aac.h | 2 |
9 files changed, 179 insertions, 28 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f330e4cb..cb2552566 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ PRINT_SUMMARY ("MOD support ......................." USE_MODPLUG MODPLUG_FOUND) PRINT_SUMMARY ("Wave support ......................" USE_SNDFILE SNDFILE_FOUND) PRINT_SUMMARY ("WavPack support ..................." USE_WAVPACK WAVPACK_FOUND) PRINT_SUMMARY ("WMA support ......................." USE_FFMPEG FFMPEG_FOUND) +PRINT_SUMMARY ("AAC support ......................." USE_AAC FAAD_FOUND) PRINT_SUMMARY ("CUE sheet support ................." USE_CUE 1) MESSAGE("") @@ -114,6 +115,3 @@ MESSAGE("") MESSAGE("File Dialogs:") PRINT_SUMMARY ("QMMP File Dialog .................." USE_QMMP_DIALOG 1) MESSAGE("") - - - @@ -21,3 +21,4 @@ CONFIG += MODPLUG_PLUGIN CONFIG += OSS_PLUGIN CONFIG += PULSE_AUDIO_PLUGIN CONFIG += ALSA_PLUGIN +CONFIG += AAC_PLUGIN 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; |
