Skip to main content
Glama
test_tempo_time_integration.py8.34 kB
"""Integration tests for tempo and time management tools.""" import pytest import asyncio class TestTempoTimeManagement: """Test tempo and time management functions.""" @pytest.mark.asyncio async def test_basic_tempo_operations(self, reaper_mcp_client): """Test getting and setting tempo.""" # Get initial tempo initial = await reaper_mcp_client.call_tool("get_master_tempo", {}) assert initial.get("success") is True assert "tempo" in initial original_tempo = initial.get("tempo") # Set new tempo new_tempo = 140.0 result = await reaper_mcp_client.call_tool("set_current_bpm", { "bpm": new_tempo, "allow_undo": True }) assert result.get("success") is True # Verify tempo changed verify = await reaper_mcp_client.call_tool("get_master_tempo", {}) assert abs(verify.get("tempo") - new_tempo) < 0.01 # Restore original tempo await reaper_mcp_client.call_tool("set_current_bpm", { "bpm": original_tempo }) @pytest.mark.asyncio async def test_play_position_tracking(self, reaper_mcp_client): """Test getting play position information.""" # Get basic position pos = await reaper_mcp_client.call_tool("get_play_position", {}) assert "position" in pos assert "is_playing" in pos assert "is_recording" in pos # Get extended position pos_ex = await reaper_mcp_client.call_tool("get_play_position_ex", {}) assert "position" in pos_ex assert "is_playing" in pos_ex assert "is_paused" in pos_ex assert "time_since_last_play" in pos_ex @pytest.mark.asyncio async def test_musical_time_conversion(self, reaper_mcp_client): """Test converting between time and beats.""" # Set known tempo await reaper_mcp_client.call_tool("set_current_bpm", {"bpm": 120.0}) # Convert time to beats (at 120 BPM, 2 seconds = 4 beats) result = await reaper_mcp_client.call_tool("time_to_beats", { "time": 2.0 }) assert result.get("success") is True assert abs(result.get("beats") - 4.0) < 0.01 # Convert beats to time result = await reaper_mcp_client.call_tool("beats_to_time", { "beats": 8.0 }) assert result.get("success") is True assert abs(result.get("time") - 4.0) < 0.01 @pytest.mark.asyncio async def test_grid_snapping(self, reaper_mcp_client): """Test snapping positions to grid.""" # Set grid to quarter notes await reaper_mcp_client.call_tool("set_grid_division", { "division": 0.25 }) # Test snapping result = await reaper_mcp_client.call_tool("snap_to_grid", { "position": 1.1 # Should snap to 1.0 at 120 BPM }) assert result.get("success") is True # Note: exact snap position depends on tempo and grid @pytest.mark.asyncio async def test_time_signature_management(self, reaper_mcp_client): """Test time signature operations.""" # Get time signature at cursor sig = await reaper_mcp_client.call_tool("get_project_time_signature", { "position": 0.0 }) assert sig.get("success") is True assert "numerator" in sig assert "denominator" in sig assert "tempo" in sig @pytest.mark.asyncio async def test_tempo_markers(self, reaper_mcp_client): """Test tempo marker management.""" # Count initial markers initial = await reaper_mcp_client.call_tool("count_tempo_markers", {}) initial_count = initial.get("count", 0) # Add tempo marker result = await reaper_mcp_client.call_tool("add_tempo_marker", { "position": 10.0, "bpm": 140.0, "time_sig_num": 3, "time_sig_denom": 4 }) assert result.get("success") is True # Verify count increased after = await reaper_mcp_client.call_tool("count_tempo_markers", {}) assert after.get("count") == initial_count + 1 # Delete the marker await reaper_mcp_client.call_tool("delete_tempo_marker", { "index": initial_count # Last added marker }) # Verify restored final = await reaper_mcp_client.call_tool("count_tempo_markers", {}) assert final.get("count") == initial_count @pytest.mark.asyncio async def test_time_formatting(self, reaper_mcp_client): """Test time formatting and parsing.""" # Format time result = await reaper_mcp_client.call_tool("format_time", { "seconds": 90.5, "format_string": "" }) assert result.get("success") is True assert "formatted" in result # Parse time string result = await reaper_mcp_client.call_tool("parse_time_string", { "time_string": "1:30" }) assert result.get("success") is True assert abs(result.get("seconds") - 90.0) < 0.1 @pytest.mark.asyncio async def test_loop_range_functions(self, reaper_mcp_client): """Test simplified loop range functions.""" # Set loop range result = await reaper_mcp_client.call_tool("set_loop_time_range", { "start": 4.0, "end": 12.0 }) assert result.get("success") is True # Get loop range result = await reaper_mcp_client.call_tool("get_loop_time_range", {}) assert result.get("success") is True assert abs(result.get("start") - 4.0) < 0.01 assert abs(result.get("end") - 12.0) < 0.01 assert result.get("is_set") is True # Clear loop await reaper_mcp_client.call_tool("set_loop_time_range", { "start": 0.0, "end": 0.0 }) class TestGenerativeTempoWorkflows: """Test generative music workflows using tempo tools.""" @pytest.mark.asyncio async def test_adaptive_tempo_generation(self, reaper_mcp_client): """Test creating adaptive tempo changes.""" # Create tempo automation for build-up positions = [0.0, 8.0, 16.0, 24.0, 32.0] tempos = [120.0, 125.0, 130.0, 140.0, 128.0] for pos, bpm in zip(positions, tempos): await reaper_mcp_client.call_tool("add_tempo_marker", { "position": pos, "bpm": bpm }) # Verify tempo at different positions for pos, expected_bpm in zip(positions, tempos): sig = await reaper_mcp_client.call_tool("get_project_time_signature", { "position": pos + 0.1 # Slightly after marker }) # Tempo should be close to expected assert abs(sig.get("tempo") - expected_bpm) < 10.0 @pytest.mark.asyncio async def test_beat_aligned_generation(self, reaper_mcp_client): """Test generating content aligned to musical beats.""" # Set consistent tempo await reaper_mcp_client.call_tool("set_current_bpm", {"bpm": 120.0}) # Create track track = await reaper_mcp_client.call_tool("insert_track", { "index": 0, "name": "Beat Aligned" }) # Generate items on beat boundaries beats = [0, 4, 8, 12, 16] # Every bar at 4/4 for beat in beats: # Convert beat to time time_result = await reaper_mcp_client.call_tool("beats_to_time", { "beats": float(beat) }) time_pos = time_result.get("time", 0.0) # Create item at beat position await reaper_mcp_client.call_tool("add_media_item", { "track_index": 0, "position": time_pos, "length": 0.5 # Half second }) # Verify items are beat-aligned count = await reaper_mcp_client.call_tool("count_track_media_items", { "track_index": 0 }) assert count.get("count") == len(beats)

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/shiehn/total-reaper-mcp'

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