Skip to main content
Glama

create_harmonics

Generate harmonic variations for audio files by adding octaves and musical intervals to create richer sound textures.

Instructions

Create harmonic variations by adding octaves and musical intervals

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
inputFileYesPath to input audio file
outputDirectoryYesDirectory for harmonic variations
octaveUpNoMix level for octave up (0-1)
octaveDownNoMix level for octave down (0-1)
fifthUpNoMix level for perfect fifth up (0-1)
thirdUpNoMix level for major third up (0-1)
overwriteNoWhether to overwrite existing output files

Implementation Reference

  • Tool definition including name, description, and input schema for validating parameters like inputFile, outputDirectory, and harmonic mix levels.
    export const createHarmonicsTool: Tool = { name: 'create_harmonics', description: 'Create harmonic variations by adding octaves and musical intervals', inputSchema: { type: 'object', properties: { inputFile: { type: 'string', description: 'Path to input audio file' }, outputDirectory: { type: 'string', description: 'Directory for harmonic variations' }, octaveUp: { type: 'number', description: 'Mix level for octave up (0-1)', minimum: 0, maximum: 1, optional: true }, octaveDown: { type: 'number', description: 'Mix level for octave down (0-1)', minimum: 0, maximum: 1, optional: true }, fifthUp: { type: 'number', description: 'Mix level for perfect fifth up (0-1)', minimum: 0, maximum: 1, optional: true }, thirdUp: { type: 'number', description: 'Mix level for major third up (0-1)', minimum: 0, maximum: 1, optional: true }, overwrite: { type: 'boolean', description: 'Whether to overwrite existing output files', default: false } }, required: ['inputFile', 'outputDirectory'] } };
  • MCP tool handler that parses arguments, constructs harmonics config, calls AdvancedAudioProcessor.createHarmonicVariations, and returns formatted results.
    case 'create_harmonics': { const input = args as any; const harmonics = { octaveUp: input.octaveUp, octaveDown: input.octaveDown, fifthUp: input.fifthUp, thirdUp: input.thirdUp }; const results = await advancedProcessor.createHarmonicVariations( input.inputFile, input.outputDirectory, harmonics, input.overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify({ success: true, harmonicsCreated: results.length, results: results }, null, 2) } ] }; }
  • Core implementation generating harmonic files by pitch-shifting input and layering original with shifted version at specified mix levels using FFmpeg operations.
    async createHarmonicVariations( inputFile: string, outputDirectory: string, harmonics: HarmonicsOperation, overwrite: boolean = false ): Promise<ProcessingResult[]> { const results: ProcessingResult[] = []; const baseName = path.parse(inputFile).name; const harmonicIntervals = [ { name: 'octave_up', semitones: 12, mix: harmonics.octaveUp }, { name: 'octave_down', semitones: -12, mix: harmonics.octaveDown }, { name: 'fifth_up', semitones: 7, mix: harmonics.fifthUp }, { name: 'third_up', semitones: 4, mix: harmonics.thirdUp } ]; for (const interval of harmonicIntervals) { if (interval.mix && interval.mix > 0) { const outputFile = path.join(outputDirectory, `${baseName}_${interval.name}${path.extname(inputFile)}` ); const operations: AudioOperations = { advanced: { pitch: { semitones: interval.semitones }, layering: { layers: [ { blend: 'mix', volume: 1 - interval.mix }, { blend: 'add', volume: interval.mix, pitch: interval.semitones } ] } } }; const result = await this.processAudioFile( inputFile, outputFile, operations, overwrite ); results.push(result); } } return results; }
  • Exports array of all tools including createHarmonicsTool for server registration.
    export const tools = [ processAudioFileTool, batchProcessAudioTool, applyPresetTool, listPresetsTool, getQueueStatusTool, generateVariationsTool, createHarmonicsTool, advancedProcessTool, layerSoundsTool ];
  • Registers the central tool request handler with switch statement covering create_harmonics case.
    export function registerTools(server: Server): void { // Register process_audio_file tool server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case 'process_audio_file': { try { const input = ProcessAudioFileInputSchema.parse(args); const result = await audioProcessor.processAudioFile( input.inputFile, input.outputFile, input.operations, (args as any).overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } catch (validationError) { // If validation fails, try with the advanced processor const result = await advancedProcessor.processAudioFile( (args as any).inputFile, (args as any).outputFile, (args as any).operations, (args as any).overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } } case 'batch_process_audio': { try { const input = BatchProcessAudioInputSchema.parse(args); const result = await audioProcessor.batchProcessAudio( { directory: input.inputDirectory, pattern: input.filePattern }, { directory: input.outputDirectory }, input.operations, (args as any).overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } catch (validationError) { // If validation fails, try with the advanced processor const result = await advancedProcessor.batchProcessAudio( { directory: (args as any).inputDirectory, pattern: (args as any).filePattern }, { directory: (args as any).outputDirectory }, (args as any).operations, (args as any).overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } } case 'apply_preset': { const input = ApplyPresetInputSchema.parse(args); const preset = getPreset(input.preset); const result = await audioProcessor.processAudioFile( input.inputFile, input.outputFile, preset.operations, (args as any).overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify({ ...result, presetUsed: preset.name, presetDescription: preset.description }, null, 2) } ] }; } case 'list_presets': { const { listPresets, getPresetsByCategory } = await import('../utils/presets.js'); const category = (args as any)?.category; const presets = category ? getPresetsByCategory(category) : listPresets(); return { content: [ { type: 'text', text: JSON.stringify(presets, null, 2) } ] }; } case 'get_queue_status': { const status = audioProcessor.getQueueStatus(); return { content: [ { type: 'text', text: JSON.stringify(status, null, 2) } ] }; } case 'generate_variations': { const input = args as any; const variations = { count: input.count || 5, pitchRange: input.pitchRange || 2, volumeRange: input.volumeRange || 3, spectralRange: input.spectralRange || 2, seed: input.seed }; const results = await advancedProcessor.generateVariations( input.inputFile, input.outputDirectory, variations, undefined, input.overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify({ success: true, variationsGenerated: results.length, results: results }, null, 2) } ] }; } case 'create_harmonics': { const input = args as any; const harmonics = { octaveUp: input.octaveUp, octaveDown: input.octaveDown, fifthUp: input.fifthUp, thirdUp: input.thirdUp }; const results = await advancedProcessor.createHarmonicVariations( input.inputFile, input.outputDirectory, harmonics, input.overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify({ success: true, harmonicsCreated: results.length, results: results }, null, 2) } ] }; } case 'advanced_process': { const input = args as any; const operations = { advanced: { pitch: input.pitch, tempo: input.tempo, spectral: input.spectral, dynamics: input.dynamics, spatial: input.spatial } }; const result = await advancedProcessor.processAudioFile( input.inputFile, input.outputFile, operations, input.overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } case 'layer_sounds': { const input = args as any; const layering = { layers: input.layers }; const result = await advancedProcessor.layerSounds( input.inputFiles, input.outputFile, layering, input.overwrite || false ); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { logger.error(`Tool execution failed: ${(error as Error).message}`); return { content: [ { type: 'text', text: JSON.stringify({ error: { code: 'TOOL_EXECUTION_FAILED', message: (error as Error).message, tool: name } }, null, 2) } ], isError: true }; } }); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DeveloperZo/mcp-audio-tweaker'

If you have feedback or need assistance with the MCP directory API, please join our Discord server