示例#1
0
//==============================================================================
void AudioDeviceManager::createDeviceTypesIfNeeded()
{
    if (availableDeviceTypes.size() == 0)
    {
        OwnedArray <AudioIODeviceType> types;
        createAudioDeviceTypes (types);

        for (int i = 0; i < types.size(); ++i)
            addAudioDeviceType (types.getUnchecked(i));

        types.clear (false);

        if (AudioIODeviceType* first = availableDeviceTypes.getFirst())
            currentDeviceType = first->getTypeName();
    }
}
//==============================================================================
void AudioDeviceManager::createDeviceTypesIfNeeded()
{
    if (availableDeviceTypes.size() == 0)
    {
        OwnedArray<AudioIODeviceType> types;
        createAudioDeviceTypes (types);

        for (auto* t : types)
            addAudioDeviceType (t);

        types.clear (false);

        if (auto* first = availableDeviceTypes.getFirst())
            currentDeviceType = first->getTypeName();
    }
}
bool BufferingAudioReader::readNextBufferChunk()
{
    const int64 pos = nextReadPosition;
    const int64 startPos = ((pos - 1024) / samplesPerBlock) * samplesPerBlock;
    const int64 endPos = startPos + numBlocks * samplesPerBlock;

    OwnedArray<BufferedBlock> newBlocks;

    for (int i = blocks.size(); --i >= 0;)
        if (blocks.getUnchecked(i)->range.intersects (Range<int64> (startPos, endPos)))
            newBlocks.add (blocks.getUnchecked(i));

    if (newBlocks.size() == numBlocks)
    {
        newBlocks.clear (false);
        return false;
    }

    for (int64 p = startPos; p < endPos; p += samplesPerBlock)
    {
        if (getBlockContaining (p) == nullptr)
        {
            newBlocks.add (new BufferedBlock (*source, p, samplesPerBlock));
            break; // just do one block
        }
    }

    {
        const ScopedLock sl (lock);
        newBlocks.swapWith (blocks);
    }

    for (int i = blocks.size(); --i >= 0;)
        newBlocks.removeObject (blocks.getUnchecked(i), false);

    return true;
}
示例#4
0
const String SAMCompiler::compile(ValueTree mdlRoot_)
{
    String dspContent;

    //==========================================================================
    // DSP file header
    //==========================================================================
    dspContent << "// This DSP file has been generated by the Synth-A-Modeler compiler.\n";
    dspContent << "import(\"physicalmodeling.lib\");\n\n";

    //==========================================================================

    ValueTree faustTree = mdlRoot_.getChildWithName(Objects::variables);
    ValueTree massTree = mdlRoot_.getChildWithName(Objects::masses);
    ValueTree linkTree = mdlRoot_.getChildWithName(Objects::links);
    ValueTree wgTree = mdlRoot_.getChildWithName(Objects::waveguides);
    ValueTree jTree = mdlRoot_.getChildWithName(Objects::junctions);
    ValueTree tTree = mdlRoot_.getChildWithName(Objects::terminations);
    ValueTree aoTree = mdlRoot_.getChildWithName(Objects::audioobjects);

    int numMasslike = 0;
    int numPorts = 0;
    int numWaveguides = 0;
    int numJunctions = 0;
    String wgTermString;
    String junctString;
    StringArray wgOutputs;
    StringArray wgInputs;
    StringArray massWithJunct;
    StringArray linkWithJunct;
    StringArray massWithJunctLine;
    StringArray portWithJunctLine;
    StringArray massWithJunctOutputs;
    StringArray junctInputs;
    StringArray junctOutputs;

    //==========================================================================

    //==========================================================================
    // Write all waveguides and terminations
    //==========================================================================
    OwnedArray<WgWithSuffixes> wgWithSuffixes;
    for (int i = 0; i < wgTree.getNumChildren(); ++i)
    {
        ++numWaveguides;
        ValueTree wg = wgTree.getChild(i);
        WgWithSuffixes* wws = new WgWithSuffixes();
        wws->wgId = wg[Ids::identifier].toString();
        ValueTree left = jTree.getChildWithProperty(Ids::identifier,
                                                    wg[Ids::startVertex]);
        ValueTree right;
        if (left.isValid())
        {
            right = tTree.getChildWithProperty(Ids::identifier,
                                               wg[Ids::endVertex]);
        }
        else
        {
            left = tTree.getChildWithProperty(Ids::identifier, wg[Ids::startVertex]);
            right = jTree.getChildWithProperty(Ids::identifier, wg[Ids::endVertex]);
        }
        ValueTree term;
        ValueTree junct;
        StringArray wgSuffixes;
        if (left.getType() == Ids::termination)
        {
            wgSuffixes.add(wgR);
            wgSuffixes.add(wgL);
            wgSuffixes.add(wgRp);
            wgSuffixes.add(wgLp);
            term = left;
            junct = right;
            wws->termRight = false;
        }
        else if (left.getType() == Ids::junction)
        {
            wgSuffixes.add(wgL);
            wgSuffixes.add(wgR);
            wgSuffixes.add(wgLp);
            wgSuffixes.add(wgRp);
            term = right;
            junct = left;
            wws->termRight = true;
        }
        wws->wgSuffixes = wgSuffixes;

        wgInputs.add(wg[Ids::identifier].toString() + wgLp);
        wgInputs.add(wg[Ids::identifier].toString() + wgRp);
        wgOutputs.add(wg[Ids::identifier].toString() + wgL);
        wgOutputs.add(wg[Ids::identifier].toString() + wgR);

        ValueTree paWg = wg.getChildWithName(Ids::parameters);
        StringArray paWgStrings;
        for (int j = 0; j < paWg.getNumChildren(); ++j)
        {
            paWgStrings.add(paWg.getChild(j)[Ids::value].toString());
        }
        wws->wgParams = paWgStrings;
        wgWithSuffixes.add(wws);

        ValueTree paTerm = term.getChildWithName(Ids::parameters);
        StringArray paTermStrings;
        for (int j = 0; j < paTerm.getNumChildren(); ++j)
        {
            paTermStrings.add(paTerm.getChild(j)[Ids::value].toString());
        }

        //======================================================================
        wgTermString << "\t";
        wgTermString << wg[Ids::identifier].toString();
        wgTermString << wgSuffixes[0] << " = " << term[Ids::identifier].toString();

        wgTermString << " : ";
        wgTermString << paWgStrings[1];
        wgTermString << ";\n\t";

        wgTermString << term[Ids::identifier].toString();
        wgTermString << " = ";
        wgTermString << wg[Ids::identifier].toString() << wgSuffixes[3];
        wgTermString << " : ";

        wgTermString << paTermStrings[0] << ";\n\n";
        //======================================================================
    }

    //==========================================================================
    // Write all junctions
    //==========================================================================
    for (int i = 0; i < jTree.getNumChildren(); ++i)
    {
        ++numJunctions;
        ValueTree junct = jTree.getChild(i);

        junctOutputs.add(junct[Ids::identifier].toString());
        junctInputs.add(junct[Ids::identifier].toString()+"p");

        ValueTree wgs = getWgForJunct(wgTree, junct);
        StringArray junctWgOuts;
        StringArray junctWgParams;

        junctString << "\t";
        for (int k = 0; k < wgs.getNumChildren(); ++k)
        {
            ValueTree wg = wgs.getChild(k);
            int wgSuffixesIdx = containsWgRef(wgWithSuffixes, wg[Ids::identifier].toString());
            if (wgSuffixesIdx == -1)
                continue;

            const StringArray& wgSuffixes = wgWithSuffixes[wgSuffixesIdx]->wgSuffixes;
            junctString << wg[Ids::identifier].toString() << wgSuffixes[1];
            junctString << " = ";
            junctString << junct[Ids::identifier].toString() << jTO;
            junctString << wg[Ids::identifier].toString();
            junctString << " : ";
            junctString << wgWithSuffixes[wgSuffixesIdx]->wgParams[1];
            junctString << ";\n\t";

            junctString << junct[Ids::identifier].toString() << jTO;
            junctString << wg[Ids::identifier].toString() << " = ";
            junctString << junct[Ids::identifier].toString() << jOutputs;
            junctString << ":(_,!)-";
            junctString << wg[Ids::identifier].toString() << wgSuffixes[2];
            junctString << ";\n\t";

            String jwo;
            jwo << wg[Ids::identifier].toString() << wgSuffixes[2];
            jwo << "*" << wgWithSuffixes[wgSuffixesIdx]->wgParams[0];
            junctWgOuts.add(jwo);

            junctWgParams.add(wgWithSuffixes[wgSuffixesIdx]->wgParams[0]);
        }


        String junctLinkString;
        String junctMassString;
        // Check if junction has one link and mass connected
        ValueTree junctLink = getJunctionLink(linkTree, junct);
        if (junctLink.isValid())
        {
            String jm;
            if (junctLink[Ids::startVertex] == junct[Ids::identifier])
                jm << junctLink[Ids::endVertex].toString();
            else
                jm << junctLink[Ids::startVertex].toString();
            junctMassString << jm << "p";

            massWithJunct.add(jm);
            massWithJunctOutputs.add(jm + "p");
            linkWithJunct.add(junctLink[Ids::identifier].toString());

            ValueTree junctLinkParams = junctLink.getChildWithName(Ids::parameters);
            StringArray junctLinkParamsStrings;
            for (int k = 0; k < junctLinkParams.getNumChildren(); ++k)
            {
                ValueTree param = junctLinkParams.getChild(k);
                junctLinkParamsStrings.add(param[Ids::value].toString());
            }
            junctLinkString << "junction" << junctLink.getType().toString();
            junctLinkString << "Underneath(0.0,";
            junctLinkString << junctLinkParamsStrings.joinIntoString(",");
            junctLinkString << ")";

            // Get mass-like object connected with junction > link
            ValueTree mwj = massTree.getChildWithProperty(Ids::identifier, jm);
            String mwjl = "\t";
            mwjl << jm;
            mwjl << " = (0.0";

            StringArray otherLinks;
            for (int k = 0; k < linkTree.getNumChildren(); ++k)
            {
                ValueTree li = linkTree.getChild(k);
                if(li[Ids::identifier].toString() == junctLink[Ids::identifier].toString())
                    continue;
                if(li[Ids::startVertex].toString() == jm)
                {
                    otherLinks.add("-"+li[Ids::identifier].toString());
                }
                else if (li[Ids::endVertex].toString() == jm)
                {
                    otherLinks.add("+"+li[Ids::identifier].toString());
                }
            }


            mwjl << otherLinks.joinIntoString(String::empty);
            mwjl << "+(";
            mwjl << junct[Ids::identifier].toString() << jOutputs << ":(!,_)))";
//            mwjl << " : ";
//            ValueTree mwjp = mwj.getChildWithName(Ids::parameters);
//            StringArray mwjpStrings;
//            for (int p = 0; p < mwjp.getNumChildren(); ++p)
//            {
//                ValueTree param = mwjp.getChild(p);
//                mwjpStrings.add(param[Ids::value].toString());
//            }
//            mwjl << mwj.getType().toString();
//            mwjl << "(" << mwjpStrings.joinIntoString(",") << ")";
            mwjl << ";";
            massWithJunctLine.add(mwjl);

        }
        else
        {
            junctMassString << "0.0";
            junctLinkString << "junctionlink(0.0, 0.0, 0.0, 0.0)";
        }
        junctString << junct[Ids::identifier].toString() << jOutputs;
        junctString << " = (";
        junctString << junctMassString << ", 0.0+";

        junctString << junctWgOuts.joinIntoString("+");
        junctString << ", 0.0+";
        junctString << junctWgParams.joinIntoString("+");

        junctString << ") : ";
        junctString << junctLinkString << ";\n\t";

        junctString << junct[Ids::identifier].toString();
        junctString << " = ";
        junctString << junct[Ids::identifier].toString() << jOutputs;
        junctString << ":(_,!);\n\n";

    }

    //==========================================================================
    // Write all faustcode
    //==========================================================================
    for (int i = 0; i < faustTree.getNumChildren(); ++i)
    {
        ValueTree fa = faustTree.getChild(i);
        dspContent << fa[Ids::identifier].toString();
        dspContent << "=";
        dspContent << fa[Ids::faustCode].toString();
        dspContent << ";\n";
    }

    dspContent << "\n";

    //==========================================================================
    // Get all mass names
    //==========================================================================
    OwnedArray<MassLinkRef> massLinkRefs;
    for (int i = 0; i < massTree.getNumChildren(); ++i)
    {
        ValueTree ma = massTree.getChild(i);
        if (massWithJunct.contains(ma[Ids::identifier].toString()))
            continue;
        MassLinkRef* mlf = new MassLinkRef();
        mlf->massId = ma[Ids::identifier].toString();
        StringArray mlfa;
        mlf->linkRefs = mlfa;
        if (ma.getType() == Ids::port)
            mlf->isPort = true;
        else
            mlf->isPort = false;
        massLinkRefs.add(mlf);
    }

    //==========================================================================
    // Write all link-like objects
    //==========================================================================
    StringArray linkobjects;
    for (int i = 0; i < linkTree.getNumChildren(); ++i)
    {
        ValueTree li = linkTree.getChild(i);
        String linkId = li[Ids::identifier].toString();
        if (linkWithJunct.contains(linkId))
            continue;
        String startVertex = li[Ids::startVertex].toString();
        String endVertex = li[Ids::endVertex].toString();
        int sIdx = containsMassLinkRef(massLinkRefs, startVertex);
        if (sIdx >= 0)
            massLinkRefs[sIdx]->linkRefs.add("-" + linkId);

        int eIdx = containsMassLinkRef(massLinkRefs, endVertex);
        if (eIdx >= 0)
            massLinkRefs[eIdx]->linkRefs.add("+" + linkId);

        String tagName = li.getType().toString();
        ValueTree params = li.getChildWithName(Ids::parameters);
        StringArray paramsStr;
        for (int k = 0; k < params.getNumChildren(); ++k)
        {
            ValueTree param = params.getChild(k);
            paramsStr.add(param[Ids::value].toString());
        }

        //======================================================================
        String linkLine;
        linkLine << "\t";
        linkLine << linkId;
        linkLine << " = (";

        linkLine << startVertex << "p - ";
        linkLine << endVertex << "p) : ";
        linkLine << tagName << "(";
        linkLine << paramsStr.joinIntoString(",") << ");";
        linkobjects.add(linkLine);
        //======================================================================
    }

    StringArray massobjects;

    //==========================================================================
    // write all mass-like object except those connected to junctions
    //==========================================================================
    for (int i = 0; i < massTree.getNumChildren(); ++i)
    {
        ValueTree ma = massTree.getChild(i);
        if (massWithJunct.contains(ma[Ids::identifier].toString()))
        {
            if(ma.getType().toString().compare("port") == 0)
                ++numPorts;
            continue;
        }

        ++numMasslike;
        String tagName = ma.getType().toString();
        String massName = ma[Ids::identifier].toString();
        String massLine;
        massLine << "\t";
        massLine << massName << " = (0.0";
        if (tagName.compare("port") == 0)
            ++numPorts;

        int mIdx = containsMassLinkRef(massLinkRefs, massName);
        if (mIdx >= 0)
        {
            if (massLinkRefs[mIdx]->linkRefs.size() > 0)
            {
                massLine << massLinkRefs[mIdx]->linkRefs.joinIntoString(String::empty);
            }
        }

        massLine << ")";
        if (tagName.compare("port") != 0)
        {
            massLine << " : ";
            massLine << tagName << "(";
            ValueTree params = ma.getChildWithName(Ids::parameters);
            StringArray paramsStr;
            for (int k = 0; k < params.getNumChildren(); ++k)
            {
                ValueTree param = params.getChild(k);
                paramsStr.add(param[Ids::value].toString());
            }
            massLine << paramsStr.joinIntoString(",") << ")";
        }
        massLine << ";";
        massobjects.add(massLine);

    }
    //==========================================================================
    // add remaining mass-like object which are connected to junctions
    //==========================================================================
    massobjects.addArray(massWithJunctLine);

    //==========================================================================
    // Write all audio objects
    //==========================================================================
    StringArray audioobjects;
    StringArray audioNames;
    for (int i = 0; i < aoTree.getNumChildren(); ++i)
    {
        ValueTree ao = aoTree.getChild(i);

        String audioLine;
        String audioName = ao[Ids::identifier].toString();
        audioNames.add(audioName);
        audioLine << "\t";
        audioLine << audioName << " = ";
        ValueTree sources = ao.getChildWithName(Ids::sources);
        String paramLine;
        StringArray paramsStr;
        if (sources.getNumChildren() > 0)
        {
            for (int k = 0; k < sources.getNumChildren(); ++k)
            {
                ValueTree src = sources.getChild(k);
                paramsStr.add(src[Ids::value].toString());
            }
            paramLine << paramsStr.joinIntoString("+");
        }

        String optional = ao[Ids::optional].toString();
        if (optional != String::empty)
        {
            if(! paramLine.startsWith("("))
                paramLine = "(" + paramLine;
            if(! paramLine.endsWith(")"))
                paramLine << ")";
            paramLine << optional;
        }
        audioLine << paramLine;
        audioLine << ";";
        audioobjects.add(audioLine);
    }

    //==========================================================================
    // Generate all inputs and outputs
    //==========================================================================
    StringArray inputs;
    StringArray inputsPorts;
    for (int i = 0; i < massLinkRefs.size(); ++i)
    {
        if (massLinkRefs[i]->isPort)
            inputsPorts.add(massLinkRefs[i]->massId);
        else
            inputs.add(massLinkRefs[i]->massId);
    }

    StringArray outputs = inputs;
    outputs.addArray(massWithJunct);
    StringArray outputsPorts = inputsPorts;

    StringArray inputsP;
    StringArray inputsPPorts;
    for (int i = 0; i < inputs.size(); ++i)
    {
        String inputP = inputs[i];
        inputP << "p";
        inputsP.add(inputP);
    }
    for (int i = 0; i < massWithJunctOutputs.size(); ++i)
    {
        ++numMasslike;
        String inputP = massWithJunctOutputs[i];
        inputsP.add(inputP);
    }
    for (int i = 0; i < inputsPorts.size(); ++i)
    {
        String inputPPort = inputsPorts[i];
        inputPPort << "p";
        inputsPPorts.add(inputPPort);
    }

    //==========================================================================
    // bibBlock with all imputs and outputs
    //==========================================================================
    dspContent << "bigBlock(" << inputsP.joinIntoString(",");
    if (wgInputs.size() > 0)
        dspContent << "," << wgInputs.joinIntoString(",");
    if (junctInputs.size() > 0)
        dspContent << "," << junctInputs.joinIntoString(",");
    if (inputsPPorts.size() > 0)
        dspContent << "," << inputsPPorts.joinIntoString(",");
    dspContent << ") = (";
    dspContent << outputs.joinIntoString(",");
    if (wgOutputs.size() > 0)
        dspContent << "," << wgOutputs.joinIntoString(",");
    if (junctOutputs.size() > 0)
        dspContent << "," << junctOutputs.joinIntoString(",");
    if (outputsPorts.size() > 0)
        dspContent << "," << outputsPorts.joinIntoString(",");
    if (audioNames.size() > 0)
        dspContent << "," << audioNames.joinIntoString(",");
    dspContent << ") with {\n";

    //==========================================================================
    // code for model objects
    //==========================================================================
    dspContent << "\n\t//waveguide termination objects\n";
    dspContent << wgTermString;
    dspContent << "\t//junctions\n";
    dspContent << junctString;
    dspContent << "\t//mass-like objects\n";
    dspContent << massobjects.joinIntoString("\n") << "\n";
    dspContent << "\n\t//link-like objects\n";
    dspContent << linkobjects.joinIntoString("\n") << "\n";
    dspContent << "\n\t//audio objects\n";
    dspContent << audioobjects.joinIntoString("\n") << "\n};\n\n";

    //==========================================================================
    // Calculate and write feedback line
    //==========================================================================
    StringArray feedbackArray;
    StringArray outputArray;
    //TODO: needs to be fixed for latest Synth-A-Modeler changes/fiyes
    int numFeedback = numMasslike - numPorts + (2 * numWaveguides) + numJunctions;
    for (int i = 0; i < numFeedback; ++i)
    {
        feedbackArray.add("_");
        outputArray.add("!");
    }
    for (int i = 0; i < numPorts + audioNames.size(); ++i)
    {
        feedbackArray.add("!");
        outputArray.add("_");
    }
    dspContent << "process = (bigBlock)~(";
    dspContent << feedbackArray.joinIntoString(",");
    dspContent << "):(";
    dspContent << outputArray.joinIntoString(",") << ");";

    //==========================================================================
    massLinkRefs.clear();
    wgWithSuffixes.clear();

    return dspContent;
}
void ProjectTreeViewBase::deleteAllSelectedItems()
{
    TreeView* tree = getOwnerView();
    const int numSelected = tree->getNumSelectedItems();
    OwnedArray <File> filesToTrash;
    OwnedArray <Project::Item> itemsToRemove;

    for (int i = 0; i < numSelected; ++i)
    {
        const ProjectTreeViewBase* const p = dynamic_cast <ProjectTreeViewBase*> (tree->getSelectedItem (i));

        if (p != nullptr)
        {
            itemsToRemove.add (new Project::Item (p->item));

            if (p->getFile().existsAsFile())
                filesToTrash.add (new File (p->getFile()));
        }
    }

    if (filesToTrash.size() > 0)
    {
        String fileList;
        const int maxFilesToList = 10;
        for (int i = jmin (maxFilesToList, filesToTrash.size()); --i >= 0;)
            fileList << filesToTrash.getUnchecked(i)->getFullPathName() << "\n";

        if (filesToTrash.size() > maxFilesToList)
            fileList << "\n...plus " << (filesToTrash.size() - maxFilesToList) << " more files...";

        int r = AlertWindow::showYesNoCancelBox (AlertWindow::NoIcon, "Delete Project Items",
                                                 "As well as removing the selected item(s) from the project, do you also want to move their files to the trash:\n\n"
                                                   + fileList,
                                                 "Just remove references",
                                                 "Also move files to Trash",
                                                 "Cancel",
                                                 tree->getTopLevelComponent());

        if (r == 0)
            return;

        if (r != 2)
            filesToTrash.clear();
    }

    ProjectTreeViewBase* treeRootItem = dynamic_cast <ProjectTreeViewBase*> (tree->getRootItem());
    jassert (treeRootItem != nullptr);

    if (treeRootItem != nullptr)
    {
        OpenDocumentManager& om = IntrojucerApp::getApp().openDocumentManager;

        for (int i = filesToTrash.size(); --i >= 0;)
        {
            const File f (*filesToTrash.getUnchecked(i));

            om.closeFile (f, false);

            if (! f.moveToTrash())
            {
                // xxx
            }
        }

        for (int i = itemsToRemove.size(); --i >= 0;)
        {
            ProjectTreeViewBase* itemToRemove = treeRootItem->findTreeViewItem (*itemsToRemove.getUnchecked(i));

            if (itemToRemove != nullptr)
            {
                om.closeFile (itemToRemove->getFile(), false);
                itemToRemove->deleteItem();
            }
        }
    }
}
示例#6
0
 ~JuceCleanup()
 {
     gDeviceTypes.clear(true);
 }
//==============================================================================
void AudioFileConverter::run()
{
	
	while ( getQueueSize() > 0 )
	{	
		{   // lock jobQueue before retrieving a task
			const ScopedLock lock (queueLock);
			task  = jobQueue[0];
		}

		/* try opening the file */
		File	inputDataFile( task->getFileName() );
		String  inputFileName( inputDataFile.getFullPathName() );

		if ( !inputDataFile.existsAsFile() || (inputDataFile.getSize() == 0) )
		{
			dbgOut(L"** AudioFileConverter ** Invalid or corrupted temporary file:\t" + inputFileName);
			removeFromQueue();
			continue;
		}
	
		/* try creating the input stream */
		FileInputStream*	fileInputStream	=	inputDataFile.createInputStream();
		if (fileInputStream == NULL)
		{
			dbgOut(L"** AudioFileConverter ** Unable to create input stream for file:\t" + inputFileName);
			removeFromQueue();
			continue;
		}
		
		dbgOut(L"");
		dbgOut(L" ***  AudioFileConverter ***");
		dbgOut(L"** AudioFileConverter ** Converting file:\t" + inputFileName 
               + L" (" + String( inputDataFile.getSize() ) + L" b)");

		int		processorOutputs = task->getChannelNumber();
		const int bytesPerSample = processorOutputs * sizeof(float);
		int		bufferSize		= task->getBufferSize();
		double	samplingRate	= task->getSamplingRate();
		int		bitDepth		= task->getBitDepth();
		String	audioFormatName = task->getFormat();

		AudioSampleBuffer tempBuffer(1, bufferSize);

		// declare classes needed to save the format
		OwnedArray<AudioFormat>			someAudioFormats;
		OwnedArray<AudioFormatWriter>	audioFormatWriters;
		OwnedArray<File>				audioFiles;
		Array<FileOutputStream*>		outStreams;
		String							audioFileName;

		AudioFormatWriter*	tmpWriter;
		FileOutputStream*	tmpStream;
		File*				tmpAudioFile;

		String outputDir = inputDataFile.getParentDirectory().getFullPathName();
	
		for (int i=0; i < processorOutputs ; i++)
		{
			// Delete temporary files
			File tmpDataFile(outputDir + File::separatorString + L"channel" + String::formatted("%.2d", i ) + ".dat");

			if ( tmpDataFile != File::nonexistent)
			{
				dbgOut( L"** AudioFileConverter ** \tDeleting temporary file:\t" + tmpDataFile.getFullPathName() );
				tmpDataFile.deleteFile();
			}
			else
			{
				dbgOut( "** AudioFileConverter ** Unable to delete temporary file:\t\t" + tmpDataFile.getFullPathName() );
			}

		
			// Define the format (wav is default)
			if (audioFormatName == "wav")
				someAudioFormats.add( new WavAudioFormat() );			
		
			else if (audioFormatName == "aiff")
				someAudioFormats.add( new AiffAudioFormat() );
		
			else if (audioFormatName == "flac")
				someAudioFormats.add( new FlacAudioFormat() );

//			else if (audioFormatName == "ogg")
//				someAudioFormats.add( new OggVorbisAudioFormat() );

			else
				someAudioFormats.add( new WavAudioFormat() );	
		
			audioFileName = outputDir + File::separatorString + "channel" + String::formatted("%.2d",i) + someAudioFormats[i]->getFileExtensions()[0];
		
			tmpAudioFile = new File (audioFileName);
			if (*tmpAudioFile == File::nonexistent)
			{
				dbgOut( L"** AudioFileConverter ** Unable to create file:\t" + audioFileName );
				audioFormatWriters.clear(true);
				someAudioFormats.clear(true);
				audioFiles.clear(true);
				outStreams.clear();

				delete fileInputStream;
				
				removeFromQueue();

				continue;
			}
		
			audioFiles.add( tmpAudioFile );

			// Delete existing files
			if (audioFiles[i]->existsAsFile())
			{
				dbgOut( "** AudioFileConverter ** \tDeleting existing audio file:\t\t" + audioFileName );			
				if	(!audioFiles[i]->deleteFile())
				{
					dbgOut( L"** AudioFileConverter ** Unable to delete existing file:\t" + audioFileName );
					audioFormatWriters.clear(true);
					someAudioFormats.clear(true);
					audioFiles.clear(true);
					outStreams.clear();
					delete fileInputStream;

					removeFromQueue();

					continue;
				}
			}

			dbgOut( "** AudioFileConverter ** \tSaving audio file:\t\t" + audioFileName );

			/* Create output stream for this file */
			tmpStream = audioFiles[i]->createOutputStream();
			if (tmpStream == NULL)
				{
					dbgOut( L"** AudioFileConverter ** Unable to create output stream for file:\t" + audioFileName );
					delete tmpAudioFile;
					audioFormatWriters.clear(true);
					someAudioFormats.clear(true);
					audioFiles.clear(true);
					outStreams.clear();
					delete fileInputStream;

					removeFromQueue();

					continue;
				}

			outStreams.add( tmpStream );
		

			/* Create Audio Format Writer */
			tmpWriter = someAudioFormats[i]->createWriterFor(	outStreams[i],		// streamToWriteTo,
																			samplingRate,		// sampleRateToUse,  
																			1,					// numberOfChannels,  
																			someAudioFormats[i]->getPossibleBitDepths().getLast(),	// bitsPerSample - Get the maximum possible bit depth for this format
																			NULL,				//  metadataValues,  
																			0 );


			if (tmpWriter == NULL)
			{
					dbgOut( L"** AudioFileConverter ** Unable to create audio format writer for:\t" + audioFileName );
					delete tmpAudioFile;
					audioFormatWriters.clear(true);
					someAudioFormats.clear(true);
					audioFiles.clear(true);
					outStreams.clear();
					delete fileInputStream;

					removeFromQueue();
		
					continue;
			}
			audioFormatWriters.add( tmpWriter );
		}

		// Write data to wav file
		int dataBlockSize = processorOutputs * bufferSize * bitDepth/8 ;
		MemoryBlock*	buffer = new MemoryBlock( dataBlockSize, true);
	
		int64 bytesSaved = inputDataFile.getSize();

		while ( !fileInputStream->isExhausted() && (fileInputStream->getPosition() <  bytesSaved) )
		{
			float* x = (float *) buffer->getData() ;

			int bytesRead = fileInputStream->read( (void *)x, dataBlockSize );
			int numSamples = (int)( bytesRead / bytesPerSample );

			for (int ch=0; ch < processorOutputs; ch++)
			{
//				const int numBytes = (int) (bytesRead/processorOutputs);

				tempBuffer.copyFrom(	0,					//  const int   	 destChannel,
										0,					//	const int  	destStartSample,
										x+ch*numSamples,	//	const float *  	source,
										numSamples			//	int  	numSamples	 
									);

				audioFormatWriters[ch]->write(	(const int**)(tempBuffer.getArrayOfChannels()),	//AudioFormatWriter *  writer,  
												numSamples				//const int  numSamples   
											  );
			}
		}

		// clean up
		delete	buffer;

		//	this should delete 'owned' objects 
		audioFormatWriters.clear(true);
		someAudioFormats.clear(true);
		audioFiles.clear(true);
		// clear the outStreams without deleting objects (already deleted)
		outStreams.clear();
	
		// Delete and close the stream
		delete fileInputStream;	

		// Delete the data.dat file
		dbgOut( L"** AudioFileConverter ** \tDeleting temporary file:\t" + inputFileName );
		inputDataFile.deleteFile();

		// Delete the task
		removeFromQueue();		
		
		dbgOut( "** AudioFileConverter ** Files saved." );

	}

	dbgOut( "** AudioFileConverter ** Thread terminates." );

}