Пример #1
0
static void import_tool(GtkWidget *w, GTKMusicBrowser *p)
{
    FileSelector *filesel = new FileSelector(p->GetContext(),"Import a Track or Playlist into My Music");
    if (filesel->Run()) {
        FAContext *m_context = p->GetContext();
        char *returnpath = filesel->GetReturnPath();
        char *filereturn = strdup_new(returnpath);
        if (filereturn)
        {
            char *first = strtok(filereturn, "\n");
            while (first) {
                char *ext = m_context->player->GetExtension(first);
                uint32 length = strlen(first) + 10;
                char *tempurl = new char[length];

                if (IsntError(FilePathToURL(first, tempurl, &length))) 
                {
                    if (ext && m_context->plm->IsSupportedPlaylistFormat(ext))
                        p->ImportPlaylist(tempurl);
                    else if (ext && 
                             m_context->player->IsSupportedExtension(ext)) 
                    {
                        PlaylistItem *plist = new PlaylistItem(tempurl);
                        m_context->plm->RetrieveMetaDataNow(plist);

                        m_context->catalog->WriteMetaDataToDatabase(tempurl,
                                                          plist->GetMetaData());
                        m_context->catalog->AddSong(tempurl);

                        delete plist;
                    }
                }
                delete [] tempurl;
                delete ext;

                first = strtok(NULL, "\n");
            }
            delete [] filereturn;
        }
    }
    delete filesel;
}
Пример #2
0
void VorbisLMC::DecodeWork()
{
   void          *pOutBuffer;
   Error          Err;
   int32          iValue;
   int32          section, ret;
   OutputInfo    *info;
   vorbis_info   *vi;
   uint32         bytesCopied, bytesPerFrame;
   int            bitrateLoops = 0;

   assert(m_pPmi);
   assert(m_pPmo);

   m_pSleepSem->Wait();
   m_pPmi->Wake();

   Err = CanDecode();
   if (Err == kError_Interrupt)
      return;
   if (Err != kError_NoErr)
   {
       m_pContext->log->Error("CanDecode returned false.\n");
       if (m_decodeInfo.sendInfo)
       {
           ReportStatus(szCannotDecode);
           m_pTarget->AcceptEvent(new Event(INFO_DoneOutputtingDueToError));
       }
       else
           ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOErrorEvent());
       return;
   }

   Err = ExtractMediaInfo();
   if (Err == kError_Interrupt)
      return;

   if (IsError(Err))
   {
       m_pContext->log->Error("ExtractMediaInfo failed: %d\n", Err);
       if (m_decodeInfo.sendInfo)
       {
           ReportStatus(szCannotDecode);
           m_pTarget->AcceptEvent(new Event(INFO_DoneOutputtingDueToError));
       }
       else
           ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOErrorEvent());
       return;
   }

   if (!m_bInit)
   {
       Err = InitDecoder();
       if (Err == kError_Interrupt)
          return;

       if (IsError(Err))
       {
           m_pContext->log->Error("Initializing the decoder failed: %d\n", Err);
           ReportError("Initializing the decoder failed.");
    
           return;
       }
   }

   m_pContext->prefs->GetPrefInt32(kDecoderThreadPriorityPref, &iValue);
   m_decoderThread->SetPriority(iValue);

   bytesCopied = 0;
   bytesPerFrame = 1;
   for (m_frameCounter = 0; !m_bExit;)
   {
      if (m_bPause)
      {
          m_pPauseSem->Wait();
          if (m_bExit)
              break;
      }

      if (m_newPos >= 0)
      {   
          ov_time_seek(&m_vf, (double)(m_newPos / iFramesPerSecond));
          m_frameCounter = m_newPos - 1;
          m_newPos = -1;
          bytesCopied = bytesPerFrame;
      }

      if (bytesCopied >= bytesPerFrame)
      {
          m_frameCounter += bytesCopied / bytesPerFrame;
          bytesCopied %= bytesPerFrame;
          ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(
             new PMOTimeInfoEvent(m_frameCounter));

          bitrateLoops++;
          if (bitrateLoops == iBitrateLoopsPerUpdate && m_decodeInfo.sendInfo)
          {
             int b;

             b = ov_bitrate_instant(&m_vf),
             vi = ov_info(&m_vf, -1);
             VorbisInfoEvent *mie = new VorbisInfoEvent(b,
                                           vi->channels, 
                                           vi->rate, 
                                           1. / (float)iFramesPerSecond);
             m_pTarget->AcceptEvent(mie);

             bitrateLoops = 0;
          }
      }

      Err = m_pOutputBuffer->BeginWrite(pOutBuffer, iDecodeBlockSize);
      if (Err == kError_Interrupt)
      {
          break;
      }
      if (Err == kError_BufferTooSmall)
      {
          if (Sleep())
             break;

          continue;
      }
      if (Err != kError_NoErr)
      {
          ReportError(szFailWrite);
          m_pContext->log->Error("LMC: Cannot write to eventbuffer: %s (%d)\n",
                                  m_szError, Err);
          break;
      } 

      section = -1;
      ret = ov_read(&m_vf, (char *)pOutBuffer, iDecodeBlockSize, 
                    0, 2, 1, &section);
      if (ret == 0)
      {
         m_pOutputBuffer->EndWrite(0);
         break;
      }

      if (section != m_section)
      { 
          vi = ov_info(&m_vf, -1);

          info = new OutputInfo;
          info->bits_per_sample = 16;
          info->number_of_channels = m_channels = vi->channels;
          info->samples_per_second = m_rate = vi->rate;
          info->samples_per_frame = vi->rate / iFramesPerSecond;
          info->max_buffer_size = 16384;
          m_frameCounter = 0;
          bytesCopied = 0;
          bytesPerFrame = (vi->rate / iFramesPerSecond) * 
                          sizeof(ogg_int16_t) * vi->channels;
          m_section = section;
       
          m_pOutputBuffer->EndWrite(0);
          ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOInitEvent(info));
          ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(
             new PMOTimeInfoEvent(m_frameCounter));

          Err = m_pOutputBuffer->BeginWrite(pOutBuffer, iDecodeBlockSize);
          if (Err != kError_NoErr)
          {
             assert(0);
          }

          vorbis_comment *comment;

          comment = ov_comment(&m_vf, -1);
          if (comment)
          {
              PlaylistItem *plItem = m_pContext->plm->GetCurrentItem();
              if (plItem)
              {
                  MetaData mdata = plItem->GetMetaData();
                  string iso;

                  char *temp;
                  temp = vorbis_comment_query(comment, "title", 0);
                  if (temp)
                  {
                      iso = ConvertToISO(temp);
                      mdata.SetTitle(iso);
                  }
 
                  temp = vorbis_comment_query(comment, "artist", 0);
                  if (temp)
                  {
                      iso = ConvertToISO(temp);
                      mdata.SetArtist(iso);
                  }

                  temp = vorbis_comment_query(comment, "album", 0);
                  if (temp)
                  {
                      iso = ConvertToISO(temp);
                      mdata.SetAlbum(iso);
                  }

                  temp = vorbis_comment_query(comment, "tracknumber", 0);
                  if (temp)
                      mdata.SetTrack(atoi(temp));

                  plItem->SetMetaData(&mdata);
                  m_pContext->target->AcceptEvent(
                             new PlaylistCurrentItemInfoEvent(plItem, 
                                                              m_pContext->plm));

              }
          }
      }
      if(ret <0) 
         ret=0; // hole/error in data - we can safely ignore this
      m_pOutputBuffer->EndWrite(ret);

      bytesCopied += ret;
   }
   ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOQuitEvent());
   ov_clear(&m_vf);

   return;
}
Пример #3
0
Error PMP300::WritePlaylist(DeviceInfo* device, 
                            vector<PlaylistItem*>* list,
                            PLMCallBackFunction function,
                            void* cookie)
{
    Error result = kError_InvalidParam;

    assert(device);
    assert(list);

    if(device && list)
    {
        result = kError_DeviceNotFound;

        if(!strcasecmp(device->GetDevice(), devices[0].device))
        {
            CRio rioInternal, rioExternal;
            bool rioPresent = false;

            rioPresent = FindRio(rioInternal, device, function, cookie);

            if(rioPresent)
            {
                FindRio(rioExternal, device, function, cookie);

                rioExternal.UseExternalFlash(true);

                if(function)
                {
                    PLMEvent event;
    
                    event.type = kPLMEvent_Status;
                    event.eventString += "A ";
                    event.eventString = device->GetDevice();
                    event.eventString += " has been found. Scanning internal memory...";

                    function(&event, cookie);
                }     

                vector<PlaylistItem*> origInternal;
                vector<PlaylistItem*> origExternal;
                vector<PlaylistItem*> newInternal;
                vector<PlaylistItem*> newExternal;
                uint32 externalTotal = 0, internalTotal = 0, usedMem; 
                uint32 count, index;
                char* path = new char[_MAX_PATH];
                char* tempPath = new char[_MAX_PATH];
                uint32 length = _MAX_PATH;

                // get a temp path
                m_context->prefs->GetPrefString(kInstallDirPref, tempPath, &length);
                strcat(tempPath, tmpnam(NULL));

#ifdef WIN32
                mkdir(tempPath);
#else
                mkdir(tempPath, S_IRWXU);
#endif

                // first get current state of device
                // we break our lists into internal and 
                // external lists for ease of organizing
                result = privateReadPlaylist(rioInternal, 
                                             false,  
                                             &internalTotal,
                                             &usedMem,
                                             &origInternal, 
                                             function, 
                                             cookie); 
                
                if(IsntError(result))
                {
                    if(function)
                    {
                        PLMEvent event;

                        event.type = kPLMEvent_Status;
                        event.eventString = "Scanning external memory...";

                        function(&event, cookie);
                    }

                    privateReadPlaylist(rioExternal, 
                                        true,  
                                        &externalTotal,
                                        &usedMem,
                                        &origExternal, 
                                        function, 
                                        cookie);    
                }

                count = list->size();
                bool useExternal = false;

                for(index = 0; index < count; index++)
                {
                    PlaylistItem* item = (*list)[index];
                    
                    if(item)
                    {
                        MetaData metadata = item->GetMetaData();

                        int32 size = metadata.Size();

                        if(!size)
                        {
                            struct stat st;

                            length = _MAX_PATH;

                            URLToFilePath(item->URL().c_str(), path, &length);

                            if(!stat(path, &st))
                                size = st.st_size;
                            else
                            {
                                result = kError_FileNoAccess;
                                break;
                            }
                        }
                        
                        // figure out where to put it...
                        uint32* memorySize;
                        vector<PlaylistItem*>* addList;

                        if(!useExternal)
                        {
                            memorySize = &internalTotal;
                            addList = &newInternal;

                            if(*memorySize < (uint32)size)
                                useExternal = true;
                            else
                                *memorySize -= size;
                        }
                        
                        if(useExternal)
                        {
                            memorySize = &externalTotal;
                            addList = &newExternal;

                            if(*memorySize < (uint32)size)
                                break;
                            else
                                *memorySize -= size;
                        }
                        
                        addList->push_back(item);
                    }
                }

                // if all is well we delete old files
                // and temporarily download files
                // that are being moved from internal
                // to external and vice versa...
                if(IsntError(result))
                {
                    if(function)
                    {
                        PLMEvent event;

                        event.type = kPLMEvent_Status;
                        event.eventString = "Deleting files...";

                        function(&event, cookie);
                    }

                    count = origInternal.size();

                    for(index = 0; index < count; index++)
                    {
                        PlaylistItem* item = origInternal[index];

                        if(find_if(newInternal.begin(), 
                                   newInternal.end(), 
                                   PlaylistItemCompare(item)) == newInternal.end())
                        {
                            // need to delete it
                            vector<PlaylistItem*>::iterator position;

                            if((position = find_if(newExternal.begin(), 
                                                   newExternal.end(), 
                                                   PlaylistItemCompare(item))) != newExternal.end())
                            {
                                // need to download it to temp file first
                                // and then upload it to other card
                                // in the next stage...

                                string itemPath = item->URL();
                                string downloadPath = tempPath;
                                downloadPath += DIR_MARKER_STR;

                                downloadPath.insert(downloadPath.size(), 
                                                    itemPath, 
                                                    itemPath.rfind('/') + 1, 
                                                    itemPath.size());

                                RioProgressStruct ps;

                                memset(&ps, 0x00, sizeof(ps));

                                ps.function = function;
                                ps.cookie = cookie;
                                ps.item = item;

                                if(!rioInternal.RxFile(downloadPath.c_str(), rioProgress, &ps))
                                {
                                    if(function)
                                    {
                                        PLMEvent event;
    
                                        event.type = kPLMEvent_Error;
                                        event.data.errorData.errorCode = rioInternal.GetErrorID();
                                        event.eventString = "Download failed, ";
                                        event.eventString += rioInternal.GetErrorStr();

                                        function(&event, cookie);
                                    }

                                    if(rioInternal.GetErrorID() == CRIO_ERROR_INTERRUPTED)
                                        result = kError_UserCancel;
                                    else
                                        result = kError_UnknownErr;
                                    break;
                                }

                                length = _MAX_PATH;
                                FilePathToURL(downloadPath.c_str(), path, &length);

                                (*position)->SetURL(path);
                            }

                            string::size_type pos = item->URL().rfind("/") + 1;
                            const char* cp = item->URL().c_str();

                            if(!rioInternal.RemoveFile(cp + pos))
                            {
                                if(function)
                                {
                                    PLMEvent event;
            
                                    event.type = kPLMEvent_Error;
                                    event.data.errorData.errorCode = rioInternal.GetErrorID();
                                    event.eventString = "Delete failed, ";
                                    event.eventString += rioInternal.GetErrorStr();

                                    function(&event, cookie);
                                }

                                result = kError_UnknownErr;
                                break;
                            }

                            delete item;
                            origInternal[index] = NULL;
                        }
                    }

                    if(IsntError(result))
                    {
                        count = origExternal.size();

                        for(index = 0; index < count; index++)
                        {
                            PlaylistItem* item = origExternal[index];

                            if(find_if(newExternal.begin(), 
                                       newExternal.end(), 
                                       PlaylistItemCompare(item)) == newExternal.end())
                            {
                                // need to delete it

                                vector<PlaylistItem*>::iterator position;

                                if((position = find_if(newInternal.begin(), 
                                                    newInternal.end(), 
                                                    PlaylistItemCompare(item))) != newInternal.end())
                                {
                                    // need to download it to temp file first
                                    // and then upload it to other card
                                    // in the next stage...
                                    
                                    string itemPath = item->URL();
                                    string downloadPath = tempPath;
                                    downloadPath += DIR_MARKER_STR;

                                    downloadPath.insert(downloadPath.size(), 
                                                        itemPath, 
                                                        itemPath.rfind('/') + 1, 
                                                        itemPath.size());

                                    RioProgressStruct ps;

                                    memset(&ps, 0x00, sizeof(ps));

                                    ps.function = function;
                                    ps.cookie = cookie;
                                    ps.item = item;

                                    if(!rioExternal.RxFile(downloadPath.c_str(), rioProgress, &ps))
                                    {
                                        if(function)
                                        {
                                            PLMEvent event;
        
                                            event.type = kPLMEvent_Error;
                                            event.data.errorData.errorCode = rioExternal.GetErrorID();
                                            event.eventString = "Download failed, ";
                                            event.eventString += rioExternal.GetErrorStr();

                                            function(&event, cookie);
                                        }

                                        if(rioInternal.GetErrorID() == CRIO_ERROR_INTERRUPTED)
                                            result = kError_UserCancel;
                                        else
                                            result = kError_UnknownErr;
                                        break;
                                    }

                                    length = _MAX_PATH;
                                    FilePathToURL(downloadPath.c_str(), path, &length);

                                    (*position)->SetURL(path);
                                }

                                string::size_type pos = item->URL().rfind("/") + 1;
                                const char* cp = item->URL().c_str();

                                if(!rioExternal.RemoveFile(cp + pos))
                                {
                                    if(function)
                                    {
                                        PLMEvent event;
        
                                        event.type = kPLMEvent_Error;
                                        event.data.errorData.errorCode = rioExternal.GetErrorID();
                                        event.eventString = "Delete failed, ";
                                        event.eventString += rioExternal.GetErrorStr();

                                        function(&event, cookie);
                                    }

                                    result = kError_UnknownErr;
                                    break;
                                }

                                delete item;
                                origExternal[index] = NULL;
                            }
                        }
                    }
                }

                // if all is well we add new files
                // to each card
                if(IsntError(result))
                {                 
                    // remove NULLs caused by deletes
                    origInternal.erase(
                        remove(origInternal.begin(), 
                               origInternal.end(), 
                               (PlaylistItem*)NULL), 
                        origInternal.end());

                    origExternal.erase(
                        remove(origExternal.begin(), 
                               origExternal.end(), 
                               (PlaylistItem*)NULL), 
                        origExternal.end());

                    // sync deletes back to the cards
                    rioInternal.TxDirectory();
                    rioExternal.TxDirectory();

                    if(function)
                    {
                        PLMEvent event;

                        event.type = kPLMEvent_Status;
                        event.eventString = "Uploading new files...";

                        function(&event, cookie);
                    }

                    count = newInternal.size();

                    for(index = 0; index < count; index++)
                    {
                        PlaylistItem* item = newInternal[index];

                        if(item->URL().find("file://") != string::npos)
                        {
                            length = _MAX_PATH;

                            URLToFilePath(item->URL().c_str(), path, &length);

                            RioProgressStruct ps;

                            memset(&ps, 0x00, sizeof(ps));

                            ps.function = function;
                            ps.cookie = cookie;
                            ps.item = item;
                            
                            if(!rioInternal.TxFile(path, rioProgress, &ps))
                            {
                                if(function)
                                {
                                    PLMEvent event;
        
                                    event.type = kPLMEvent_Error;
                                    event.data.errorData.errorCode = rioInternal.GetErrorID();
                                    event.eventString = "Upload failed, ";
                                    event.eventString += rioInternal.GetErrorStr();

                                    function(&event, cookie);
                                }

                                if(rioInternal.GetErrorID() == CRIO_ERROR_INTERRUPTED)
                                    result = kError_UserCancel;
                                else
                                    result = kError_UnknownErr;
                                break;
                            }

                            origInternal.push_back(new PlaylistItem(*item));
                        }
                    }

                    if(IsntError(result))
                    {
                        count = newExternal.size();

                        for(index = 0; index < count; index++)
                        {
                            PlaylistItem* item = newExternal[index];

                            if(item->URL().find("file://") != string::npos)
                            {
                                length = _MAX_PATH;

                                URLToFilePath(item->URL().c_str(), path, &length);

                                RioProgressStruct ps;

                                memset(&ps, 0x00, sizeof(ps));

                                ps.function = function;
                                ps.cookie = cookie;
                                ps.item = item;
                            
                                if(!rioExternal.TxFile(path, rioProgress, &ps))
                                {
                                    if(function)
                                    {
                                        PLMEvent event;
        
                                        event.type = kPLMEvent_Error;
                                        event.data.errorData.errorCode = rioExternal.GetErrorID();
                                        event.eventString = "Upload failed, ";
                                        event.eventString += rioExternal.GetErrorStr();

                                        function(&event, cookie);
                                    }

                                    if(rioExternal.GetErrorID() == CRIO_ERROR_INTERRUPTED)
                                        result = kError_UserCancel;
                                    else
                                        result = kError_UnknownErr;
                                    break;
                                }

                                origExternal.push_back(new PlaylistItem(*item));
                            }
                        }
                    }
                }

                // finally put it all in the correct order
                // and we should be done!
                if(IsntError(result))
                {
                    uint32 entryOrder[ CRIO_MAX_DIRENTRY ];

	                count = newInternal.size();

                    if(count)
                    {

                        for(index = 0; index < count; index++)
                        {
                            vector<PlaylistItem*>::iterator position;
                            PlaylistItem* item = newInternal[index];

                            if((position = find_if(origInternal.begin(), 
                                                  origInternal.end(), 
                                                  PlaylistItemCompare(item))) != origInternal.end())
                            {
//#ifdef WIN32
//								distance(origInternal.begin(), position /*, entryOrder[index] */ );
//#else
								entryOrder[index] = distance(origInternal.begin(), position /*, entryOrder[index] */ );
//#endif
                            }

                        }

                        rioInternal.SetFileOrder(entryOrder, count);
                    }

                    count = newExternal.size();

                    if(count)
                    {
                        for(index = 0; index < count; index++)
                        {
                            vector<PlaylistItem*>::iterator position;
                            PlaylistItem* item = newExternal[index];

                            if((position = find_if(origExternal.begin(), 
                                                  origExternal.end(), 
                                                  PlaylistItemCompare(item))) != origExternal.end())
                            {
//#ifdef WIN32
//                                distance(origExternal.begin(), position /*, entryOrder[index] */ );
//#else	                            
								entryOrder[index] = distance(origExternal.begin(), position /*, entryOrder[index] */ );
//#endif

                            }
                        }

                        rioExternal.SetFileOrder(entryOrder, count);
                    }

                    // sync uploads back to the cards
                    rioInternal.TxDirectory();
                    rioExternal.TxDirectory();
                }

                if(function)
                {
                    PLMEvent event;

                    event.type = kPLMEvent_Done;

                    function(&event, cookie);
                }

                // clean up
                length = _MAX_PATH;
                FilePathToURL(tempPath, path, &length);
                strcpy(tempPath, path);

                count = origInternal.size();

                for(index = 0; index < count; index++)
                {
                    PlaylistItem* item = origInternal[index];

                    if(item->URL().find(tempPath) != string::npos)
                    {
                        length = _MAX_PATH;

                        URLToFilePath(item->URL().c_str(), path, &length);

                        remove(path);
                    }

                    delete item;
                }

                count = origExternal.size();

                for(index = 0; index < count; index++)
                {
                    PlaylistItem* item = origExternal[index];

                    if(item->URL().find(tempPath) != string::npos)
                    {
                        length = _MAX_PATH;

                        URLToFilePath(item->URL().c_str(), path, &length);

                        remove(path);
                    }

                    delete item;
                }
 
                
                URLToFilePath(tempPath, path, &length);
                rmdir(path);

                delete [] tempPath;
                delete [] path;
            }
        }       
    }

    return result;
}