toolsandutils/e32tools/wveconv/wveconv.cpp
changeset 0 83f4b4db085c
child 1 d4b442d23379
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolsandutils/e32tools/wveconv/wveconv.cpp	Tue Feb 02 01:39:43 2010 +0200
@@ -0,0 +1,250 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Psion3a WVE to Series5 sound file convertor
+// 
+//
+
+#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
+#include <iostream>
+#include <fstream>
+using namespace std;
+#else  //!__MSVCDOTNET__
+#include <iostream.h>
+#include <fstream.h>
+#ifdef __CW32__
+using std::streampos;
+#endif //__CW32__
+#endif //__MSVCDOTNET__
+
+#include <string.h>
+
+#if defined(__VC32__) && !defined(__MSVCDOTNET__)
+#pragma warning( disable : 4710 )	// 'fn': function not inlined
+#endif // old MSVC
+
+#define KUidRecordApp 0x1000007e
+
+#define KUid1 0x10000037
+#define KUid2 0x1000006d
+#define KUid3 KUidRecordApp
+#define KUidCheckSum 0x5508accf
+
+#define KUidAppStream 0x10000089
+#define KUidSampleStream 0x10000052
+
+
+int ErrorNotWveFile()
+	{
+	cout << "The specified input file is not a Series 3a WVE file" << endl ;
+	return(0);
+	}
+
+int ErrorNotFound()
+	{
+	cout << "Unable to open input file" << endl ;
+	return(0);
+	}
+
+int ReadInt32(ifstream& inStream)
+	{
+    char ch[4];
+    inStream.read(&ch[0],4);
+    return *(int*)&ch[0];
+	}
+
+int ReadInt16(ifstream& inStream)
+	{
+    char ch[4];
+    inStream.read(&ch[0],2);
+    ch[2]=0;
+    ch[3]=0;
+    return *(int*)&ch[0];
+	}
+
+int WriteWord(ofstream& outStream,unsigned int aWord)
+	{
+    outStream.write((char*)&aWord,4);
+	return 0;
+	}
+
+int WriteByte(ofstream& outStream,const char aByte)
+	{
+    outStream.write((char*)&aByte,1);
+	return 0;
+	}
+
+int WriteText(ofstream& outStream,const char* aText)
+	{
+	char ch;
+	while((ch=*aText++)!=0)
+		outStream << ch;
+	return 0;
+	}
+
+void ShowHelp()
+	{
+	cout << "WveConv 0.04";
+	cout << endl ;
+	cout << "Converts a Psion 3a WVE file to an EPOC sound file" << endl ;
+	cout << endl ;
+	cout << "Usage: WVECONV S3AFILE.WVE [EPOCFILE]" << endl ;
+	cout << endl ;
+	cout << "If [EPOCFILE] is omitted, the input filename" << endl ;
+    cout << "without the extension will be used" << endl ;
+	}
+
+int ConvertFile(const char* inputFile,const char* outputFile)
+	{
+	ifstream inStream(inputFile,ios::in|ios::binary);
+	ofstream outStream(outputFile,ios::out|ios::binary);
+
+	if(!inStream.is_open())
+		return(ErrorNotFound());
+
+	const char* appName="Record.app";
+	char header[16];
+	
+	inStream.read(&header[0],16);
+
+	if(strcmp(header,"ALawSoundFile**")!=0)
+		return(ErrorNotWveFile());
+
+	int compressedLength=0;
+	int trailingSilence=0;
+	int compressorUid=0;
+	int sampleLength=0;
+	int repeatCount=0;
+    int versionNumber=0;
+//
+// extract the sample length, repeat count and trailing silence...
+//
+	versionNumber=ReadInt16(inStream);
+	sampleLength=ReadInt32(inStream);
+	trailingSilence=ReadInt16(inStream);
+	repeatCount=ReadInt16(inStream);
+    if(repeatCount==0) // 0 and 1 are the same on Series 3 
+        repeatCount=1; 
+
+	trailingSilence*=31250;
+
+	compressedLength=sampleLength;
+
+	cout << "Converting " << inputFile << " to " << outputFile << endl << endl;
+    cout << "Version number  :" << versionNumber << endl ;
+	cout << "Sample length   :" << sampleLength << " bytes" << endl ;
+	cout << "Repeat count    :" << repeatCount << endl ;
+	cout << "Trailing silence:" << trailingSilence << " uS" << endl ;
+
+	inStream.seekg((streampos)0x20);
+//
+// Write out the header...
+//
+	unsigned int rootstreamid=0x14;
+	unsigned int appstreamid=0x25;
+	unsigned int samplestreamid=0x34;
+
+// checked uid header
+
+	WriteWord(outStream,KUid1);
+	WriteWord(outStream,KUid2);
+	WriteWord(outStream,KUidRecordApp);
+	WriteWord(outStream,KUidCheckSum);
+
+// root stream id
+
+	WriteWord(outStream,rootstreamid);
+
+//stream dictionary @ 0x14 root stream
+
+	WriteByte(outStream,4);		// two entries in dictionary
+	WriteWord(outStream,KUidSampleStream);	// sample stream
+	WriteWord(outStream,samplestreamid);
+	WriteWord(outStream,KUidAppStream);	// appid stream
+	WriteWord(outStream,appstreamid);
+
+// record app identifier stream @ 0x25
+
+	WriteWord(outStream,KUidRecordApp);
+	WriteByte(outStream,42);
+	WriteText(outStream,appName);
+
+//  sample header @ 0x34
+
+	WriteWord(outStream,sampleLength);
+	WriteWord(outStream,compressorUid);
+	WriteWord(outStream,repeatCount-1); // repeats are zero based on Series 5 
+	WriteWord(outStream,trailingSilence);
+	WriteWord(outStream,compressedLength);
+//
+// Copy the sample data...
+//
+	streampos newPos=0x20; // start of sample data in 3a file...
+	inStream.seekg(newPos);
+
+	char buffer[256];
+	int count;
+	int actualLength=0;
+	do
+		{
+		inStream.read(&buffer[0],256);
+		if((count=inStream.gcount())!=0)
+			{
+			outStream.write(&buffer[0],count);
+			actualLength+=count;
+			}
+		} while(count);
+//
+// should check actualLength==sampleLength...but what the heck
+//
+	outStream.close();
+	inStream.close();
+	return 0;
+	}
+
+int main(int aNumArgs,char* aArgs[])
+	{
+	if(aNumArgs<=1 || aArgs[1][0]=='?' || aArgs[1][0]=='/')
+		{
+		ShowHelp();
+		return 0;
+		}
+	char inputFile[255];
+	char outputFile[255];
+
+	strcpy(inputFile,aArgs[1]);
+
+	if(aNumArgs==3)
+		strcpy(outputFile,aArgs[2]);
+
+	if(aNumArgs==2 || outputFile[0]==0)
+		{
+		strcpy(outputFile,inputFile);
+//
+// remove the extension
+//
+		int len=strlen(outputFile);
+		for(;;)
+			{
+			if(--len<0)
+				break;
+			if(outputFile[len]=='.')
+				{
+				outputFile[len]=0;
+				break;
+				}
+			}
+		}
+	return(ConvertFile(inputFile,outputFile));
+	}
+