PageRenderTime 23ms CodeModel.GetById 1ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/cores/paplayer/SIDCodec.cpp

http://github.com/xbmc/xbmc
C++ | 153 lines | 108 code | 22 blank | 23 comment | 16 complexity | 78b0a97f2a9c2a6ef279561b3995ff6d MD5 | raw file
  1/*
  2 *      Copyright (C) 2005-2013 Team XBMC
  3 *      http://xbmc.org
  4 *
  5 *  This Program is free software; you can redistribute it and/or modify
  6 *  it under the terms of the GNU General Public License as published by
  7 *  the Free Software Foundation; either version 2, or (at your option)
  8 *  any later version.
  9 *
 10 *  This Program is distributed in the hope that it will be useful,
 11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *  GNU General Public License for more details.
 14 *
 15 *  You should have received a copy of the GNU General Public License
 16 *  along with XBMC; see the file COPYING.  If not, see
 17 *  <http://www.gnu.org/licenses/>.
 18 *
 19 */
 20
 21#include "SIDCodec.h"
 22#include "cores/DllLoader/DllLoader.h"
 23#include "FileItem.h"
 24#include "utils/log.h"
 25#include "utils/URIUtils.h"
 26#include "cores/AudioEngine/Utils/AEUtil.h"
 27
 28SIDCodec::SIDCodec()
 29{
 30  m_CodecName = "sid";
 31  m_sid = 0;
 32  m_iTrack = -1;
 33  m_iDataPos = -1;
 34}
 35
 36SIDCodec::~SIDCodec()
 37{
 38  DeInit();
 39}
 40
 41bool SIDCodec::Init(const CStdString &strFile, unsigned int filecache)
 42{
 43  if (!m_dll.Load())
 44    return false; // error logged previously
 45
 46  m_dll.Init();
 47
 48  CStdString strFileToLoad = strFile;
 49  m_iTrack = 0;
 50  if (URIUtils::HasExtension(strFile, ".sidstream"))
 51  {
 52    //  Extract the track to play
 53    CStdString strFileName=URIUtils::GetFileName(strFile);
 54    int iStart=strFileName.ReverseFind('-')+1;
 55    m_iTrack = atoi(strFileName.substr(iStart, strFileName.size()-iStart-10).c_str());
 56    //  The directory we are in, is the file
 57    //  that contains the bitstream to play,
 58    //  so extract it
 59    strFileToLoad = URIUtils::GetDirectory(strFile);
 60    URIUtils::RemoveSlashAtEnd(strFileToLoad); // we want the filename
 61  }
 62
 63  m_sid = m_dll.LoadSID(strFileToLoad.c_str());
 64  if (!m_sid)
 65  {
 66    CLog::Log(LOGERROR,"SIDCodec: error opening file %s!",strFile.c_str());
 67    return false;
 68  }
 69
 70  m_Channels = 1;
 71  m_SampleRate = 48000;
 72  m_BitsPerSample = 16;
 73  m_TotalTime = 4*60*1000;
 74  m_DataFormat = AE_FMT_S16NE;
 75
 76  return true;
 77}
 78
 79void SIDCodec::DeInit()
 80{
 81  if (m_sid)
 82    m_dll.FreeSID(m_sid);
 83  m_sid = 0;
 84}
 85
 86int64_t SIDCodec::Seek(int64_t iSeekTime)
 87{
 88  char temp[3840*2];
 89  if (m_iDataPos > iSeekTime/1000*48000*2)
 90  {
 91    m_dll.StartPlayback(m_sid,m_iTrack);
 92    m_iDataPos = 0;
 93  }
 94
 95  while (m_iDataPos < iSeekTime/1000*48000*2)
 96  {
 97    int64_t iRead = iSeekTime/1000*48000*2-m_iDataPos;
 98    if (iRead > 3840*2)
 99    {
100      m_dll.SetSpeed(m_sid,32*100);
101      iRead = 3840*2;
102    }
103    else
104      m_dll.SetSpeed(m_sid,100);
105
106    iRead = m_dll.FillBuffer(m_sid,temp,int(iRead));
107    if (!iRead)
108      break; // get out of here
109    if (iRead == 3840*2)
110      m_iDataPos += iRead*32;
111    else m_iDataPos += iRead;
112  }
113  return iSeekTime;
114}
115
116int SIDCodec::ReadPCM(BYTE *pBuffer, int size, int *actualsize)
117{
118  if (m_iDataPos == -1)
119  {
120    m_dll.StartPlayback(m_sid,m_iTrack);
121    m_iDataPos = 0;
122  }
123
124  if (m_iDataPos >= m_TotalTime/1000*48000*2)
125    return READ_EOF;
126
127  m_dll.SetSpeed(m_sid,100);
128  if ((*actualsize=m_dll.FillBuffer(m_sid,pBuffer,size))> 0)
129  {
130    m_iDataPos += *actualsize;
131    return READ_SUCCESS;
132  }
133
134  return READ_ERROR;
135}
136
137bool SIDCodec::CanInit()
138{
139  return m_dll.CanLoad();
140}
141
142CAEChannelInfo SIDCodec::GetChannelInfo()
143{
144  static enum AEChannel map[1][2] = {
145    {AE_CH_FC, AE_CH_NULL}
146  };
147
148  if (m_Channels > 1)
149    return CAEUtil::GuessChLayout(m_Channels);
150
151  return CAEChannelInfo(map[m_Channels - 1]);
152}
153