oggChainSplitter.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 //===========================================================================
00031 
00032 // oggChainSplitter.cpp : Defines the entry point for the console application.
00033 //
00034 
00035 #include "stdafx.h"
00036 
00037 #include <libOOOgg/libOOOgg.h>
00038 #include <libOOOgg/dllstuff.h>
00039 #include "VorbisComments.h"
00040 #include <iostream>
00041 #include <fstream>
00042 #include <vector>
00043 
00044 unsigned long bytePos = 0;
00045 bool needComments = false;
00046 bool inStream = false;
00047 fstream outFile;
00048 string inFileName;
00049 string outFileName;
00050 VorbisComments currentComment;
00051 unsigned long chainCount = 0;
00052 bool isOK = true;
00053 
00054 bool renameCurrentFile() {
00055         cout<<"Renaming File..."<<endl;
00056         if ((currentComment.numUserComments() > 0)) {
00057                 vector<SingleVorbisComment*> locArtists = currentComment.getCommentsByKey("artist");
00058                 vector<SingleVorbisComment*> locTitles = currentComment.getCommentsByKey("title");
00059                 string locArtist = "Unknown_Artist";
00060                 string locTitle = "Unknown_Title";
00061 
00062                 cout<<"Basics done..."<<endl;
00063                 if (locArtists.size() > 0) {
00064                         locArtist = locArtists[0]->value();
00065                 }
00066 
00067                 if (locTitles.size() > 0) {
00068                         locTitle = locTitles[0]->value();
00069                 }
00070 
00071                 string locPartialName = locArtist+"_"+locTitle;
00072 
00073                 size_t locSlashPos = outFileName.find_last_of('\\');
00074                 if (locSlashPos == string::npos) {
00075                         locSlashPos = -1;
00076                 }
00077                 size_t locDotPos = outFileName.find_last_of('.');
00078 
00079                 cout<<"Before substitution..."<<endl;
00080                 string locNewName = outFileName.substr(0,locSlashPos + 1) + locPartialName + outFileName.substr(locDotPos);
00081                 cout<<"After subst."<<endl;
00082                 cout<<"Renaming "<<outFileName<<" to "<<locNewName<<endl;
00083 #ifdef WIN32
00084                 MoveFile(outFileName.c_str(), locNewName.c_str());
00085 #else  /* assume POSIX */
00086                 rename(outFileName.c_str(), locNewName.c_str());
00087 #endif                
00088         }
00089 
00090         return true;
00091 
00092 }
00093 bool writePage(OggPage* inOggPage) {
00094         //cout << "Writing page "<<endl;
00095         unsigned char* pageBuff = inOggPage->createRawPageData();
00096         //cout <<pageBuff<<endl;
00097         outFile.write((char*)pageBuff, inOggPage->pageSize());
00098         //cout<<"Written..."<<endl;
00099         delete[] pageBuff;
00100         //cout<<"After delete"<<endl;
00101         return true;
00102 }
00103 //This will be called by the callback
00104 bool pageCB(OggPage* inOggPage, void*  /* inUserData  ignored */) {
00105         bool retVal = false;
00106         if (inStream == false) {
00107                 //Not in the middle of a stream
00108                 if (inOggPage->header()->isBOS()) {
00109                         //Case 1 : Not in the middle of a stream and we found a BOS... start a new file.
00110                         char* locNum = new char[32];
00111                         sprintf(locNum, "%d", chainCount);
00112                         // ^ is the same as: itoa(chainCount, locNum, 10);
00113                         outFileName = inFileName + "__" + locNum + ".ogg";
00114                         cout<<"New output file "<<outFileName<<endl;
00115                 
00116                         delete locNum;
00117                         locNum = NULL;
00118                         outFile.open(outFileName.c_str(), ios_base::out | ios_base::binary);
00119                         retVal = writePage(inOggPage);
00120                         inStream = retVal;
00121                         needComments = true;
00122                         
00123                 } else {
00124                         //Case 2 : Not in middle of stream and not BOS - ERROR
00125                         cout << "BOS Page expected at "<<bytePos<<endl;
00126                         retVal = false;
00127                 }
00128 
00129         } else {
00130                 //In the middle of a stream
00131                 if (inOggPage->header()->isEOS()) {
00132                         //Case 3 : It's the last page of the current stream... write it out and switch state.
00133                         retVal = writePage(inOggPage);
00134                         outFile.close();
00135                         renameCurrentFile();
00136                         cout<<"Closing file number "<<chainCount<<endl;
00137                         chainCount++;
00138                         inStream = false;
00139                         
00140                 } else {
00141                         //Case 4 : It's just a normal page write it out.
00142                         if (needComments) {
00143                                 currentComment.parseOggPacket(inOggPage->getPacket(0), 7);
00144                         }
00145                         retVal = writePage(inOggPage);
00146                 }
00147         }
00148 
00149         isOK = retVal;
00150         delete inOggPage;
00151         return retVal;
00152 
00153 }
00154 
00155 #ifdef WIN32
00156 int __cdecl _tmain(int argc, _TCHAR* argv[])
00157 #else
00158 int main(int argc, char * argv[])
00159 #endif
00160 {
00161         //This program just dumps the pages out of a file in ogg format.
00162         // Currently does not error checking. Check your command line carefully !
00163         // USAGE :: oggChainSplitter <OggFile>
00164         //
00165 
00166         bytePos = 0;
00167 
00168         if (argc < 2) {
00169                 cout<<"Usage : oggChainSplitter <filename>"<<endl;
00170                 cout<<"Only splits vorbis chained streams... careful with command line... no error checks"<<endl;
00171         } else {
00172                 cout << "Starting..."<<endl;
00173                 OggDataBuffer testOggBuff;
00174                 
00175                 testOggBuff.registerStaticCallback(&pageCB, NULL);
00176 
00177                 fstream testFile;
00178                 inFileName = argv[1];
00179                 testFile.open(argv[1], ios_base::in | ios_base::binary);
00180                 
00181                 const unsigned short BUFF_SIZE = 8092;
00182                 char* locBuff = new char[BUFF_SIZE];
00183                 while ((!testFile.eof()) && (isOK)) {
00184                         testFile.read(locBuff, BUFF_SIZE);
00185                         unsigned long locBytesRead = testFile.gcount();
00186                 testOggBuff.feed((const unsigned char*)locBuff, locBytesRead);
00187                 }
00188 
00189                 delete[] locBuff;
00190         }
00191 
00192         return 0;
00193 }
00194 

Generated on Tue Feb 15 14:54:23 2005 for oggdsf by  doxygen 1.3.9