# Development ## Prerequisites - Android Studio Hedgehog or newer - Android SDK API 27+ - NDK (Native Development Kit) - Android device with microphone ## Build ```bash # Clone the repository git clone cd ToneForge # Open in Android Studio or build via command line ./gradlew assembleDebug ``` ## Project Structure ### **🆕 Modern MVP Architecture** The project has been completely refactored to use: - **MVP Pattern**: Model-View-Presenter for clean architecture - **Repository Pattern**: Unified data access layer - **Navigation Controller**: Decoupled navigation system - **Responsive Layouts**: ConstraintLayout with adaptive dimensions - **Comprehensive Testing**: Unit, integration, and UI tests ### **Technologies Used** - **Gradle**: Build system - **CMake**: Native code build - **JNI**: Java-C++ interface - **AudioRecord/AudioTrack**: Android audio API - **Fragments**: Multi-screen navigation with MVP - **RecyclerView**: Drag-and-drop interface - **SharedPreferences**: Data persistence - **ConstraintLayout**: Modern responsive layouts - **Espresso/JUnit**: Testing framework ## Compatibility - **Minimum Android**: 8.1 (API 27) - **Architectures**: ARM64, ARM32, x86, x86_64 - **Sample rate**: 48kHz - **Format**: PCM Float 32-bit - **Channels**: Mono (input and output) ## 🆕 **Development with MVP Architecture** ### **Creating a New Fragment** Follow the MVP pattern established in the project: 1. **Create the Contract**: ```java public interface MyContract { interface View extends BaseView { void updateData(String data); void showProgress(); void hideProgress(); } interface Presenter extends BasePresenter { void loadData(); void onUserAction(); } } ``` 2. **Implement the Presenter**: ```java public class MyPresenter implements MyContract.Presenter { private WeakReference viewRef; private AudioRepository audioRepository; public MyPresenter(Context context, AudioRepository repository) { this.audioRepository = repository; } @Override public void loadData() { ifViewAttached(view -> { view.showProgress(); // Load data and update view view.updateData("Loaded data"); view.hideProgress(); }); } } ``` 3. **Create the Fragment**: ```java public class MyFragment extends BaseFragment implements MyContract.View { @Override protected MyContract.Presenter createPresenter() { return new MyPresenter( requireContext(), AudioRepository.getInstance(requireContext()) ); } @Override public void updateData(String data) { // Update UI with data } } ``` ### **Testing Your Components** Write comprehensive tests for your presenter: ```java @Test public void testPresenter_loadData() { // Arrange MyPresenter presenter = new MyPresenter(context, mockRepository); presenter.attachView(mockView); // Act presenter.loadData(); // Assert verify(mockView).showProgress(); verify(mockView).updateData(anyString()); verify(mockView).hideProgress(); } ``` ### **Layout Guidelines** Follow responsive design principles: ```xml android:layout_margin="@dimen/margin_medium" android:textSize="@dimen/text_size_large"