Page 1 of 1

Sample editor in Usine

Posted: 21 Apr 2026, 10:46
by sm_jamieson
I believe the sample editor in Usine can read wav and aif files.
It seems Usine would be a good platform to set sample loop points etc.

Can it or a patch do the following:
1. Set and play a loop
2. Add loop start and end cue points to metadata
3. Snap cue to zero crossing point
4. Modify sample to cross fade across loop points.
5. Save the sample in the same or different format with loop cue points in the metadata that can be used by another sampler ?

Thanks.

Re: Sample editor in Usine

Posted: 21 Apr 2026, 17:29
by oli_lab
Hi !
The sampler modules can't save metadata so it is not possible out of th box.
But I did an addon called "player with saved markers" that can save and retrieved markers.
It is not possible to do loops at sample level but.

for this king of thing, I rather use REAPER and make regionss to be render or a specialized sample editor.

Otherwise, I pretty much like the idea of using Usine as a modular studio to produce processed samples (just like with an old school hardware studio)

Image

Re: Sample editor in Usine

Posted: 21 Apr 2026, 19:06
by sm_jamieson
Ok thanks. I'm now using extreme sample converter which does excellent auto looping.

But I think Usine should have read and write sample modules that support wav and aif at least and the metadata for looping
It could be written with the SDK ...

Re: Sample editor in Usine

Posted: 21 Apr 2026, 19:41
by oli_lab
The SDKaudiosample does not manage the metadata, I had a go with C++ libs, but I quit after "a while"

here is the "NOT working" code :

Code: Select all

void diywt::writeWavFile(const std::string& filename) {
	realSize = m_maxWrite;
	sdkTraceInt(realSize);
	sdkTraceInt(m_lastMarkerNumber);

	// Structures pour les en-têtes
	struct RiffHeader {
		char chunkId[4] = { 'R', 'I', 'F', 'F' };
		uint32_t chunkSize;
		char format[4] = { 'W', 'A', 'V', 'E' };
	};

	struct FmtChunk {
		char chunkId[4] = { 'f', 'm', 't', ' ' };
		uint32_t chunkSize = 16;
		uint16_t audioFormat = 3; // 32-bit float
		uint16_t numChannels;
		uint32_t sampleRate;
		uint32_t byteRate;
		uint16_t blockAlign;
		uint16_t bitsPerSample;
	};

	struct DataChunk {
		char chunkId[4] = { 'd', 'a', 't', 'a' };
		uint32_t chunkSize;
	};

	std::ofstream outFile(filename, std::ios::binary);
	if (!outFile) {
		sdkTraceErrorChar("can't open file");
		return;
	}

	// Paramètres audio
	int numChannels = 1;
	int bitsPerSample = 32;
	int numSamples = m_markersStart[m_lastMarkerNumber];//realSize;

	// Calculer la taille des données audio
	uint32_t dataSize = numSamples * numChannels * bitsPerSample / 8;

	// Remplir les en-têtes
	RiffHeader riffHeader;
	FmtChunk fmtChunk;
	fmtChunk.numChannels = numChannels;
	fmtChunk.sampleRate = sdkGetSampleRate();
	fmtChunk.byteRate = fmtChunk.sampleRate * numChannels * bitsPerSample / 8;
	fmtChunk.blockAlign = numChannels * bitsPerSample / 8;
	fmtChunk.bitsPerSample = bitsPerSample;

	DataChunk dataChunk;
	dataChunk.chunkSize = dataSize;

	// Calculer la taille totale du fichier
	uint32_t totalFileSize = sizeof(RiffHeader) + sizeof(FmtChunk) + sizeof(DataChunk) + dataSize;// +sizeof(CueChunk) + cueChunkSize + sizeof(AdtlChunk) + adtlChunkSize;
	riffHeader.chunkSize = totalFileSize - 8; // Soustraire les 8 octets du chunkId et du chunkSize

	// Écrire les en-têtes dans le fichier
	outFile.write(reinterpret_cast<char*>(&riffHeader), sizeof(RiffHeader));
	outFile.write(reinterpret_cast<char*>(&fmtChunk), sizeof(FmtChunk));
	outFile.write(reinterpret_cast<char*>(&dataChunk), sizeof(DataChunk));

	// Écrire les données audio
	for (f = 0; f < numSamples; ++f) {
		outFile.write(reinterpret_cast<const char*>(&m_audioBuffer[f]), sizeof(float));
	}

	// Ajouter un padding si nécessaire pour aligner le chunk suivant sur un nombre pair d'octets
	if (dataSize % 2 != 0) {
		outFile.put(0);
	}

	outFile.close();
/*	//mettre à jour la sortie markerOut
	int tempSize = m_lastMarkerNumber;
	markersOut.setSize(tempSize);
	for (int m = 0; m < tempSize; m++) {
		markersOut.setArrayData(m, float(m_markersStart[m])/float(numSamples));
	}*/


	if (!outFile) {
		sdkTraceErrorChar("Error closing file");
		return;
	}

	std::string s = fdrFileName.getPChar();
	s = s + " successfully created";
	sdkTraceChar(s.c_str());
	m_signalisation = 2;
}