New upstream version 0.4.1
Bret Curtis
6 years ago
0 | Edit files for version number (and possibly other changes) : | |
1 | - djgpp/config.h | |
2 | - os2/config.h | |
3 | - amiga/config.h | |
4 | - android/jni/config.h | |
5 | ||
6 | Edit files for possibly other changes: | |
7 | - djgpp/Makefile | |
8 | - os2/makefile | |
9 | - amiga/Makefile* | |
10 | - amiga/*.cfg | |
11 | - android/* | |
12 | - android/jni/*.mk |
0 | os: | |
1 | - linux | |
2 | - osx | |
3 | osx_image: xcode7.2 | |
4 | dist: trusty | |
5 | sudo: required | |
0 | 6 | language: c |
1 | compiler: | |
2 | - gcc | |
3 | - clang | |
4 | 7 | env: |
5 | 8 | - BUILD_TYPE=Debug |
6 | 9 | - BUILD_TYPE=Release |
7 | 10 | matrix: |
8 | allow_failures: | |
9 | - compiler: clang | |
11 | include: | |
12 | - os: linux | |
13 | env: | |
14 | ANALYZE="scan-build-3.6 --use-cc clang-3.6 --use-c++ clang++-3.6 " | |
15 | compiler: clang | |
10 | 16 | branches: |
11 | 17 | only: |
12 | 18 | - master |
19 | - coverity_scan | |
13 | 20 | - /wildmidi-.*$/ |
21 | ||
14 | 22 | before_install: |
15 | - pwd | |
16 | - git submodule update --init --recursive | |
17 | - echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse" | |
18 | - echo "yes" | sudo apt-add-repository ppa:psi29a/precise | |
19 | - sudo apt-get update -qq | |
20 | - sudo apt-get install -qq cmake | |
21 | - sudo apt-get install -qq libgtest-dev google-mock | |
22 | - sudo apt-get install -qq libasound2-dev libopenal-dev | |
23 | - sudo mkdir /usr/src/gtest/build | |
24 | - cd /usr/src/gtest/build | |
25 | - sudo cmake .. -DBUILD_SHARED_LIBS=1 | |
26 | - sudo make -j4 | |
27 | - sudo ln -s /usr/src/gtest/build/libgtest.so /usr/lib/libgtest.so | |
28 | - sudo ln -s /usr/src/gtest/build/libgtest_main.so /usr/lib/libgtest_main.so | |
23 | - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_install.linux.sh; fi | |
24 | - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_install.osx.sh; fi | |
29 | 25 | before_script: |
30 | - cd - | |
31 | - mkdir build | |
32 | - cd build | |
33 | - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. | |
26 | - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_script.linux.sh; fi | |
27 | - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi | |
34 | 28 | script: |
35 | - make -j2 | |
29 | - cd ./build | |
30 | - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j3; fi | |
36 | 31 | |
37 | #after_script: | |
38 | # - ./runtests | |
39 | 32 | notifications: |
40 | 33 | irc: |
41 | 34 | channels: |
0 | #!/bin/sh | |
1 | ||
2 | if [ "${ANALYZE}" ]; then | |
3 | echo "yes" | sudo add-apt-repository "deb http://llvm.org/apt/`lsb_release -sc`/ llvm-toolchain-`lsb_release -sc`-3.6 main" | |
4 | wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add - | |
5 | fi | |
6 | ||
7 | echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse" | |
8 | echo "yes" | sudo apt-add-repository ppa:psi29a/`lsb_release -sc` | |
9 | sudo apt-get update -qq | |
10 | sudo apt-get install -qq libgtest-dev google-mock | |
11 | sudo apt-get install -qq libopenal-dev | |
12 | if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi | |
13 | sudo mkdir /usr/src/gtest/build | |
14 | cd /usr/src/gtest/build | |
15 | sudo cmake .. | |
16 | sudo make -j4 | |
17 | sudo ln -s /usr/src/gtest/build/libgtest.so /usr/lib/libgtest.so | |
18 | sudo ln -s /usr/src/gtest/build/libgtest_main.so /usr/lib/libgtest_main.so |
0 | #!/bin/sh | |
1 | ||
2 | brew update | |
3 | brew rm cmake || true | |
4 | brew rm pkgconfig || true | |
5 | brew install cmake pkgconfig |
0 | #!/bin/sh | |
1 | ||
2 | free -m | |
3 | mkdir build | |
4 | cd build | |
5 | export CODE_COVERAGE=1 | |
6 | if [ "${CC}" = "clang" ]; then export CODE_COVERAGE=0; fi | |
7 | ${ANALYZE}cmake .. -DBUILD_WITH_CODE_COVERAGE=${CODE_COVERAGE} -DBUILD_UNITTESTS=1 -DCMAKE_INSTALL_PREFIX=/usr -DBINDIR=/usr/bin -DCMAKE_BUILD_TYPE="None" |
0 | #!/bin/bash | |
1 | ||
2 | while [ $# -gt 0 ]; do | |
3 | ARGSTR=$1 | |
4 | shift | |
5 | ||
6 | if [ ${ARGSTR:0:1} != "-" ]; then | |
7 | echo "Unknown argument $ARGSTR" | |
8 | echo "Try '$0 -h'" | |
9 | exit 1 | |
10 | fi | |
11 | ||
12 | for (( i=1; i<${#ARGSTR}; i++ )); do | |
13 | ARG=${ARGSTR:$i:1} | |
14 | case $ARG in | |
15 | V ) | |
16 | VERBOSE=true ;; | |
17 | ||
18 | v ) | |
19 | VS_VERSION=$1 | |
20 | shift ;; | |
21 | ||
22 | d ) | |
23 | SKIP_DOWNLOAD=true ;; | |
24 | ||
25 | e ) | |
26 | SKIP_EXTRACT=true ;; | |
27 | ||
28 | k ) | |
29 | KEEP=true ;; | |
30 | ||
31 | u ) | |
32 | UNITY_BUILD=true ;; | |
33 | ||
34 | p ) | |
35 | PLATFORM=$1 | |
36 | shift ;; | |
37 | ||
38 | c ) | |
39 | CONFIGURATION=$1 | |
40 | shift ;; | |
41 | ||
42 | h ) | |
43 | cat <<EOF | |
44 | Usage: $0 [-cdehkpuvV] | |
45 | ||
46 | Options: | |
47 | -c <Release/Debug> | |
48 | Set the configuration, can also be set with environment variable CONFIGURATION. | |
49 | -d | |
50 | Skip checking the downloads. | |
51 | -e | |
52 | Skip extracting dependencies. | |
53 | -h | |
54 | Show this message. | |
55 | -k | |
56 | Keep the old build directory, default is to delete it. | |
57 | -p <Win32/Win64> | |
58 | Set the build platform, can also be set with environment variable PLATFORM. | |
59 | -u | |
60 | Configure for unity builds. | |
61 | -v <2013/2015> | |
62 | Choose the Visual Studio version to use. | |
63 | -V | |
64 | Run verbosely | |
65 | EOF | |
66 | exit 0 | |
67 | ;; | |
68 | ||
69 | * ) | |
70 | echo "Unknown argument $ARG." | |
71 | echo "Try '$0 -h'" | |
72 | exit 1 ;; | |
73 | esac | |
74 | done | |
75 | done | |
76 | ||
77 | if [ -z $VERBOSE ]; then | |
78 | STRIP="> /dev/null 2>&1" | |
79 | fi | |
80 | if [ -z $VS_VERSION ]; then | |
81 | VS_VERSION="2013" | |
82 | fi | |
83 | ||
84 | if [ -z $APPVEYOR ]; then | |
85 | echo "Running prebuild outside of Appveyor." | |
86 | ||
87 | DIR=$(echo "$0" | sed "s,\\\\,/,g" | sed "s,\(.\):,/\\1,") | |
88 | cd $(dirname "$DIR")/.. | |
89 | else | |
90 | echo "Running prebuild in Appveyor." | |
91 | ||
92 | cd $APPVEYOR_BUILD_FOLDER | |
93 | VERSION="$(cat README.md | grep Version: | awk '{ print $3; }')-$(git rev-parse --short HEAD)" | |
94 | appveyor UpdateBuild -Version "$VERSION" > /dev/null & | |
95 | fi | |
96 | ||
97 | run_cmd() { | |
98 | CMD="$1" | |
99 | shift | |
100 | ||
101 | if [ -z $VERBOSE ]; then | |
102 | eval $CMD $@ > output.log 2>&1 | |
103 | RET=$? | |
104 | ||
105 | if [ $RET -ne 0 ]; then | |
106 | if [ -z $APPVEYOR ]; then | |
107 | echo "Command $CMD failed, output can be found in `real_pwd`/output.log" | |
108 | else | |
109 | echo | |
110 | echo "Command $CMD failed;" | |
111 | cat output.log | |
112 | fi | |
113 | else | |
114 | rm output.log | |
115 | fi | |
116 | ||
117 | return $RET | |
118 | else | |
119 | eval $CMD $@ | |
120 | return $? | |
121 | fi | |
122 | } | |
123 | ||
124 | download() { | |
125 | if [ $# -lt 3 ]; then | |
126 | echo "Invalid parameters to download." | |
127 | return 1 | |
128 | fi | |
129 | ||
130 | NAME=$1 | |
131 | shift | |
132 | ||
133 | echo "$NAME..." | |
134 | ||
135 | while [ $# -gt 1 ]; do | |
136 | URL=$1 | |
137 | FILE=$2 | |
138 | shift | |
139 | shift | |
140 | ||
141 | if ! [ -f $FILE ]; then | |
142 | printf " Downloading $FILE... " | |
143 | ||
144 | if [ -z $VERBOSE ]; then | |
145 | curl --silent --retry 10 -kLy 5 -o $FILE $URL | |
146 | RET=$? | |
147 | else | |
148 | curl --retry 10 -kLy 5 -o $FILE $URL | |
149 | RET=$? | |
150 | fi | |
151 | ||
152 | if [ $RET -ne 0 ]; then | |
153 | echo "Failed!" | |
154 | else | |
155 | echo "Done." | |
156 | fi | |
157 | else | |
158 | echo " $FILE exists, skipping." | |
159 | fi | |
160 | done | |
161 | ||
162 | if [ $# -ne 0 ]; then | |
163 | echo "Missing parameter." | |
164 | fi | |
165 | } | |
166 | ||
167 | real_pwd() { | |
168 | pwd | sed "s,/\(.\),\1:," | |
169 | } | |
170 | ||
171 | CMAKE_OPTS="" | |
172 | add_cmake_opts() { | |
173 | CMAKE_OPTS="$CMAKE_OPTS $@" | |
174 | } | |
175 | ||
176 | RUNTIME_DLLS="" | |
177 | add_runtime_dlls() { | |
178 | RUNTIME_DLLS="$RUNTIME_DLLS $@" | |
179 | } | |
180 | ||
181 | OSG_PLUGINS="" | |
182 | add_osg_dlls() { | |
183 | OSG_PLUGINS="$OSG_PLUGINS $@" | |
184 | } | |
185 | ||
186 | if [ -z $PLATFORM ]; then | |
187 | PLATFORM=`uname -m` | |
188 | fi | |
189 | ||
190 | if [ -z $CONFIGURATION ]; then | |
191 | CONFIGURATION="Debug" | |
192 | fi | |
193 | ||
194 | case $VS_VERSION in | |
195 | 14|2015 ) | |
196 | GENERATOR="Visual Studio 14 2015" | |
197 | XP_TOOLSET="v140_xp" | |
198 | ;; | |
199 | ||
200 | # 12|2013| | |
201 | * ) | |
202 | GENERATOR="Visual Studio 12 2013" | |
203 | XP_TOOLSET="v120_xp" | |
204 | ;; | |
205 | esac | |
206 | ||
207 | case $PLATFORM in | |
208 | x64|x86_64|x86-64|win64|Win64 ) | |
209 | ARCHNAME=x86-64 | |
210 | ARCHSUFFIX=64 | |
211 | BITS=64 | |
212 | ||
213 | BASE_OPTS="-G\"$GENERATOR Win64\"" | |
214 | add_cmake_opts "-G\"$GENERATOR Win64\"" | |
215 | ;; | |
216 | ||
217 | x32|x86|i686|i386|win32|Win32 ) | |
218 | ARCHNAME=x86 | |
219 | ARCHSUFFIX=86 | |
220 | BITS=32 | |
221 | ||
222 | BASE_OPTS="-G\"$GENERATOR\" -T$XP_TOOLSET" | |
223 | add_cmake_opts "-G\"$GENERATOR\"" -T$XP_TOOLSET | |
224 | ;; | |
225 | ||
226 | * ) | |
227 | echo "Unknown platform $PLATFORM." | |
228 | exit 1 | |
229 | ;; | |
230 | esac | |
231 | ||
232 | case $CONFIGURATION in | |
233 | debug|Debug|DEBUG ) | |
234 | CONFIGURATION=Debug | |
235 | ;; | |
236 | ||
237 | release|Release|RELEASE ) | |
238 | CONFIGURATION=Release | |
239 | ;; | |
240 | ||
241 | relwithdebinfo|RelWithDebInfo|RELWITHDEBINFO ) | |
242 | CONFIGURATION=RelWithDebInfo | |
243 | ;; | |
244 | esac | |
245 | ||
246 | echo | |
247 | echo "==========================" | |
248 | echo "Starting prebuild on win$BITS" | |
249 | echo "==========================" | |
250 | echo | |
251 | ||
252 | mkdir -p deps | |
253 | cd deps | |
254 | ||
255 | DEPS="`pwd`" | |
256 | ||
257 | if [ -z $SKIP_DOWNLOAD ]; then | |
258 | echo "Downloading dependency packages." | |
259 | echo | |
260 | ||
261 | # OpenAL | |
262 | download "OpenAL-Soft 1.16.0" \ | |
263 | http://kcat.strangesoft.net/openal-binaries/openal-soft-1.16.0-bin.zip \ | |
264 | OpenAL-Soft-1.16.0.zip | |
265 | ||
266 | fi | |
267 | ||
268 | cd .. #/.. | |
269 | ||
270 | # Set up dependencies | |
271 | if [ -z $KEEP ]; then | |
272 | echo | |
273 | printf "Preparing build directory... " | |
274 | ||
275 | rm -rf Build_$BITS | |
276 | mkdir -p Build_$BITS/deps | |
277 | ||
278 | echo Done. | |
279 | fi | |
280 | mkdir -p Build_$BITS/deps | |
281 | cd Build_$BITS/deps | |
282 | ||
283 | DEPS_INSTALL=`pwd` | |
284 | cd $DEPS | |
285 | ||
286 | echo | |
287 | echo "Extracting dependencies..." | |
288 | ||
289 | # OpenAL | |
290 | printf "OpenAL-Soft 1.16.0... " | |
291 | { | |
292 | if [ -d openal-soft-1.16.0-bin ]; then | |
293 | printf "Exists. " | |
294 | elif [ -z $SKIP_EXTRACT ]; then | |
295 | rm -rf openal-soft-1.16.0-bin | |
296 | eval 7z x -y OpenAL-Soft-1.16.0.zip $STRIP | |
297 | fi | |
298 | ||
299 | OPENAL_SDK="`real_pwd`/openal-soft-1.16.0-bin" | |
300 | ||
301 | add_cmake_opts -DOPENAL_INCLUDE_DIR="$OPENAL_SDK/include/AL" \ | |
302 | -DOPENAL_LIBRARY="$OPENAL_SDK/libs/Win$BITS/OpenAL32.lib" | |
303 | ||
304 | echo Done. | |
305 | } | |
306 | ||
307 | cd $DEPS_INSTALL/.. | |
308 | ||
309 | echo | |
310 | echo "Setting up WildMIDI build..." | |
311 | ||
312 | if [ -z $VERBOSE ]; then | |
313 | printf " Configuring... " | |
314 | else | |
315 | echo " cmake .. $CMAKE_OPTS" | |
316 | fi | |
317 | ||
318 | run_cmd cmake .. $CMAKE_OPTS | |
319 | RET=$? | |
320 | ||
321 | if [ -z $VERBOSE ]; then | |
322 | if [ $RET -eq 0 ]; then echo Done. | |
323 | else echo Failed.; fi | |
324 | fi | |
325 | ||
326 | echo | |
327 | ||
328 | # NOTE: Disable this when/if we want to run test cases | |
329 | if [ -z $CI ]; then | |
330 | echo "Copying Runtime DLLs..." | |
331 | mkdir -p $CONFIGURATION | |
332 | for DLL in $RUNTIME_DLLS; do | |
333 | echo " `basename $DLL`." | |
334 | cp "$DLL" $CONFIGURATION/ | |
335 | done | |
336 | ||
337 | echo "Copying Runtime Resources/Config Files" | |
338 | ||
339 | echo " wildmidi.cfg" | |
340 | cp $CONFIGURATION/../cfg/wildmidi.cfg $CONFIGURATION/wildmidi.cfg | |
341 | fi | |
342 | ||
343 | exit $RET |
0 | #!/bin/sh | |
1 | ||
2 | export CXX=clang++ | |
3 | export CC=clang | |
4 | ||
5 | DEPENDENCIES_ROOT="/private/tmp/wildmidi-deps/wildmidi-deps" | |
6 | ||
7 | mkdir build | |
8 | cd build | |
9 | ||
10 | cmake \ | |
11 | -D CMAKE_EXE_LINKER_FLAGS="-lz" \ | |
12 | -D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT" \ | |
13 | -D CMAKE_OSX_DEPLOYMENT_TARGET="10.8" \ | |
14 | -D CMAKE_OSX_SYSROOT="macosx10.11" \ | |
15 | -D CMAKE_BUILD_TYPE=Debug \ | |
16 | -D WANT_OSX_DEPLOYMENT=TRUE \ | |
17 | -G"Unix Makefiles" \ | |
18 | .. |
0 | #!/bin/bash | |
1 | ||
2 | if [ -z $PLATFORM ]; then | |
3 | PLATFORM=`uname -m` | |
4 | fi | |
5 | ||
6 | if [ -z $CONFIGURATION ]; then | |
7 | CONFIGURATION="Debug" | |
8 | fi | |
9 | ||
10 | case $PLATFORM in | |
11 | x32|x86|i686|i386|win32|Win32 ) | |
12 | BITS=32 | |
13 | PLATFORM=Win32 | |
14 | ;; | |
15 | ||
16 | x64|x86_64|x86-64|win64|Win64 ) | |
17 | BITS=64 | |
18 | PLATFORM=x64 | |
19 | ;; | |
20 | ||
21 | * ) | |
22 | echo "Unknown platform $PLATFORM." | |
23 | exit 1 ;; | |
24 | esac | |
25 | ||
26 | if [ -z $APPVEYOR ]; then | |
27 | echo "Running $BITS-bit $CONFIGURATION build outside of Appveyor." | |
28 | ||
29 | DIR=$(echo "$0" | sed "s,\\\\,/,g" | sed "s,\(.\):,/\\1,") | |
30 | cd $(dirname "$DIR")/.. | |
31 | else | |
32 | echo "Running $BITS-bit $CONFIGURATION build in Appveyor." | |
33 | ||
34 | cd $APPVEYOR_BUILD_FOLDER | |
35 | fi | |
36 | ||
37 | cd build_$BITS | |
38 | ||
39 | which msbuild > /dev/null | |
40 | if [ $? -ne 0 ]; then | |
41 | msbuild() { | |
42 | /c/Program\ Files\ \(x86\)/MSBuild/12.0/Bin/MSBuild.exe "$@" | |
43 | } | |
44 | fi | |
45 | ||
46 | if [ -z $APPVEYOR ]; then | |
47 | msbuild WildMIDI.sln //t:Build //m:8 | |
48 | else | |
49 | msbuild WildMIDI.sln //t:Build //m:8 //logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" | |
50 | fi | |
51 | ||
52 | RET=$? | |
53 | if [ $RET -eq 0 ] && [ ! -z $PACKAGE ]; then | |
54 | msbuild PACKAGE.vcxproj //t:Build //m:8 | |
55 | RET=$? | |
56 | fi | |
57 | ||
58 | exit $RET |
4 | 4 | # WildMIDI Version |
5 | 5 | SET(VERSION_MAJOR 0) |
6 | 6 | SET(VERSION_MINOR 4) |
7 | SET(VERSION_RELEASE 0) | |
7 | SET(VERSION_RELEASE 1) | |
8 | 8 | SET(WILDMIDI_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}") |
9 | 9 | |
10 | 10 | # Lib Versions |
11 | 11 | SET(SOVERSION 2) |
12 | SET(VERSION 2.0.0) | |
12 | SET(VERSION 2.0.1) | |
13 | 13 | |
14 | 14 | # Find Macros |
15 | 15 | SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) |
21 | 21 | INCLUDE(TestBigEndian) |
22 | 22 | |
23 | 23 | # Set a default build type if none was specified |
24 | IF(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") | |
25 | MESSAGE(STATUS "Setting build type to 'Debug' as none was specified.") | |
26 | SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) | |
27 | # Set the possible values of build type for cmake-gui | |
28 | SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") | |
29 | ENDIF() | |
24 | IF (NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") | |
25 | MESSAGE(STATUS "Setting build type to 'Debug' as none was specified.") | |
26 | SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) | |
27 | # Set the possible values of build type for cmake-gui | |
28 | SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") | |
29 | ENDIF () | |
30 | 30 | SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}") |
31 | 31 | MESSAGE(STATUS "Build Type: ${CMAKE_BUILD_TYPE}") |
32 | 32 | |
33 | 33 | # Set our optoins |
34 | OPTION(WANT_PLAYER "Build WildMIDI player in addition to the libraries" ON) | |
35 | OPTION(WANT_STATIC "Build static library in addition to dynamic library" OFF) | |
36 | CMAKE_DEPENDENT_OPTION(WANT_PLAYERSTATIC "Build a statically linked WildMIDI player" ON "WANT_STATIC" OFF) | |
37 | OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" OFF) | |
38 | OPTION(WANT_OSS "Include OSS (Open Sound System) support" OFF) | |
39 | #OPTION(WANT_COREAUDIO "Include CoreAudio support (Driver support for Mac OS X" OFF) | |
40 | OPTION(WANT_OPENAL "Include OpenAL suport (Cross Platform) support" OFF) | |
41 | OPTION(WANT_DEVTEST "Build WildMIDI DevTest file to check files" OFF) | |
42 | IF(UNIX AND NOT APPLE) | |
43 | SET(WILDMIDI_CFG "/etc/wildmidi/wildmidi.cfg" CACHE STRING "default config location") | |
44 | ELSE() | |
45 | SET(WILDMIDI_CFG "wildmidi.cfg" CACHE STRING "default config location") | |
46 | ENDIF() | |
34 | OPTION(BUILD_SHARED_LIBS "Build a dynamic wildmidi library" ON) | |
35 | OPTION(WANT_PLAYER "Build WildMIDI player in addition to the libraries" ON) | |
36 | OPTION(WANT_STATIC "Build static library in addition to dynamic library" OFF) | |
37 | CMAKE_DEPENDENT_OPTION(WANT_PLAYERSTATIC "Build a statically linked WildMIDI player" ON "WANT_STATIC;WANT_PLAYER" OFF) | |
38 | OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" OFF) | |
39 | OPTION(WANT_OSS "Include OSS (Open Sound System) support" OFF) | |
40 | OPTION(WANT_OPENAL "Include OpenAL suport (Cross Platform) support" OFF) | |
41 | OPTION(WANT_DEVTEST "Build WildMIDI DevTest file to check files" OFF) | |
42 | OPTION(WANT_OSX_DEPLOYMENT "OSX Deployment" OFF) | |
43 | IF (WIN32 AND MSVC) | |
44 | OPTION(WANT_MP_BUILD "Build with Multiple Processes (/MP)" OFF) | |
45 | ENDIF () | |
46 | IF (UNIX AND NOT APPLE) | |
47 | SET(WILDMIDI_CFG "/etc/wildmidi/wildmidi.cfg" CACHE STRING "default config location") | |
48 | ELSE () | |
49 | SET(WILDMIDI_CFG "wildmidi.cfg" CACHE STRING "default config location") | |
50 | ENDIF () | |
51 | ||
52 | IF ((NOT BUILD_SHARED_LIBS) AND (NOT WANT_STATIC)) | |
53 | MESSAGE(FATAL_ERROR "Neither dynamic nor static library build is selected.") | |
54 | ENDIF () | |
55 | ||
47 | 56 | |
48 | 57 | # Platform specific defines |
49 | IF(UNIX) | |
58 | IF (UNIX) | |
50 | 59 | # allow 'large' files in 32 bit builds |
51 | 60 | ADD_DEFINITIONS( |
52 | -D_LARGEFILE_SOURCE | |
53 | -D_FILE_OFFSET_BITS=64 | |
54 | -D_LARGE_FILES | |
55 | ) | |
56 | ENDIF() | |
57 | ||
58 | IF(WIN32) | |
61 | -D_LARGEFILE_SOURCE | |
62 | -D_FILE_OFFSET_BITS=64 | |
63 | -D_LARGE_FILES | |
64 | ) | |
65 | ENDIF (UNIX) | |
66 | ||
67 | IF (OPENBSD) # Set RPATH for OpenBSD so WildMIDI can find libWildMidi.so | |
68 | # use, i.e. don't skip the full RPATH for the build tree | |
69 | SET(CMAKE_SKIP_BUILD_RPATH FALSE) | |
70 | ||
71 | # when building, don't use the install RPATH already | |
72 | # (but later on when installing) | |
73 | SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) | |
74 | ||
75 | SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") | |
76 | ||
77 | # add the automatically determined parts of the RPATH | |
78 | # which point to directories outside the build tree to the install RPATH | |
79 | SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) | |
80 | ||
81 | # the RPATH to be used when installing, but only if it's not a system directory | |
82 | LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) | |
83 | IF ("${isSystemDir}" STREQUAL "-1") | |
84 | SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") | |
85 | ENDIF () | |
86 | ENDIF (OPENBSD) | |
87 | ||
88 | IF (WIN32) | |
59 | 89 | ADD_DEFINITIONS( |
60 | -DWIN32_LEAN_AND_MEAN | |
61 | -D_CRT_SECURE_NO_WARNINGS | |
62 | ) | |
63 | ENDIF() | |
90 | -DNOMINMAX | |
91 | -DWIN32_LEAN_AND_MEAN | |
92 | -D_CRT_SECURE_NO_WARNINGS | |
93 | ) | |
94 | ENDIF (WIN32) | |
64 | 95 | |
65 | 96 | # Compiler specific settings |
66 | IF(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") | |
97 | IF (CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang")) | |
67 | 98 | ADD_DEFINITIONS( |
68 | -Wall -W | |
69 | -fno-common | |
70 | ) | |
71 | ||
72 | IF(NOT WIN32 AND NOT CYGWIN) | |
99 | -Wall -W | |
100 | -fno-common | |
101 | ) | |
102 | ||
103 | IF (NOT WIN32 AND NOT CYGWIN) | |
73 | 104 | SET(OLD_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") |
74 | 105 | SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS} -Werror") |
75 | 106 | CHECK_C_SOURCE_COMPILES("int foo(void) __attribute__((visibility(\"default\"))); |
76 | 107 | int main(void) {return 0;}" HAVE_VISIBILITY_DEFAULT) |
77 | IF(HAVE_VISIBILITY_DEFAULT) | |
108 | IF (HAVE_VISIBILITY_DEFAULT) | |
78 | 109 | CHECK_C_COMPILER_FLAG(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) |
79 | ENDIF() | |
110 | ENDIF () | |
80 | 111 | SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}") |
81 | ENDIF() | |
112 | ENDIF () | |
82 | 113 | |
83 | 114 | IF (CMAKE_BUILD_TYPE STREQUAL "Debug") |
84 | ADD_DEFINITIONS( -ggdb3 -O0 ) | |
85 | ELSEIF(CMAKE_BUILD_TYPE STREQUAL "Release") | |
86 | ADD_DEFINITIONS( -O3 ) | |
87 | ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug") | |
88 | ENDIF() | |
89 | ||
90 | IF("${CMAKE_C_COMPILER_ID}" MATCHES "SunPro") | |
115 | ADD_DEFINITIONS(-ggdb3 -O0) | |
116 | ELSEIF (CMAKE_BUILD_TYPE STREQUAL "Release") | |
117 | ADD_DEFINITIONS(-O3) | |
118 | ENDIF (CMAKE_BUILD_TYPE STREQUAL "Debug") | |
119 | ENDIF () | |
120 | ||
121 | IF (CMAKE_C_COMPILER_ID MATCHES "SunPro") | |
91 | 122 | SET(OLD_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") |
92 | 123 | SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS} -xldscope=hidden") |
93 | # __SUNPRO_C >= 0x590 | |
94 | # CHECK_C_SOURCE_COMPILES("int foo(void) __attribute__((visibility(\"default\"))); | |
95 | # int main(void) {return 0;}" HAVE_VISIBILITY_DEFAULT) | |
96 | # __SUNPRO_C >= 0x550 | |
124 | # __SUNPRO_C >= 0x590 | |
125 | # CHECK_C_SOURCE_COMPILES("int foo(void) __attribute__((visibility(\"default\"))); | |
126 | # int main(void) {return 0;}" HAVE_VISIBILITY_DEFAULT) | |
127 | # __SUNPRO_C >= 0x550 | |
97 | 128 | CHECK_C_SOURCE_COMPILES("__global int foo(void); |
98 | 129 | int main(void) {return 0;}" HAVE_LDSCOPE_GLOBAL) |
99 | IF(HAVE_LDSCOPE_GLOBAL)# OR HAVE_VISIBILITY_DEFAULT | |
130 | IF (HAVE_LDSCOPE_GLOBAL)# OR HAVE_VISIBILITY_DEFAULT | |
100 | 131 | SET(HAVE_LDSCOPE_HIDDEN 1) |
101 | ENDIF() | |
132 | ENDIF () | |
102 | 133 | SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}") |
103 | ENDIF() | |
134 | ENDIF () | |
104 | 135 | |
105 | 136 | CHECK_C_SOURCE_COMPILES("int main(void) {__builtin_expect(0,0); return 0;}" HAVE___BUILTIN_EXPECT) |
106 | 137 | |
121 | 152 | SET(AUDIODRV_OPENAL) |
122 | 153 | |
123 | 154 | # UNIX-like environments |
124 | IF(UNIX AND NOT APPLE) | |
155 | IF (UNIX AND NOT APPLE) | |
125 | 156 | |
126 | 157 | # Go looking for available sound packages for WildMIDI player |
127 | IF(WANT_PLAYER OR WANT_PLAYERSTATIC) | |
158 | IF (WANT_PLAYER) | |
128 | 159 | FIND_PACKAGE(ALSA) |
129 | 160 | FIND_PACKAGE(OpenAL) |
130 | 161 | FIND_PACKAGE(OSS) |
131 | 162 | |
132 | 163 | # Set preferred output |
133 | IF(WANT_ALSA) | |
134 | IF(NOT ALSA_FOUND) | |
164 | IF (WANT_ALSA) | |
165 | IF (NOT ALSA_FOUND) | |
135 | 166 | MESSAGE(FATAL_ERROR "ALSA required but not found.") |
136 | ENDIF() | |
167 | ENDIF () | |
137 | 168 | SET(AUDIODRV_ALSA 1) |
138 | 169 | SET(AUDIO_LIBRARY ${ALSA_LIBRARY}) |
139 | 170 | |
140 | ELSEIF(WANT_OSS) | |
141 | IF(NOT OSS_FOUND) | |
171 | ELSEIF (WANT_OSS) | |
172 | IF (NOT OSS_FOUND) | |
142 | 173 | MESSAGE(FATAL_ERROR "OSS required but not found.") |
143 | ENDIF() | |
174 | ENDIF () | |
144 | 175 | # no special header paths |
145 | 176 | SET(AUDIODRV_OSS 1) |
146 | 177 | SET(AUDIO_LIBRARY ${OSS_LIBRARY}) |
147 | 178 | |
148 | ELSEIF(WANT_OPENAL) | |
149 | IF(NOT OPENAL_FOUND) | |
179 | ELSEIF (WANT_OPENAL) | |
180 | IF (NOT OPENAL_FOUND) | |
150 | 181 | MESSAGE(FATAL_ERROR "OpenAL required but not found.") |
151 | ENDIF() | |
182 | ENDIF () | |
152 | 183 | SET(AUDIODRV_OPENAL 1) |
153 | 184 | SET(AUDIO_LIBRARY ${OPENAL_LIBRARY}) |
154 | 185 | |
155 | ELSE() # Try to auto-detect | |
156 | ||
157 | IF(ALSA_FOUND) | |
186 | ELSE () # Try to auto-detect | |
187 | ||
188 | IF (ALSA_FOUND) | |
158 | 189 | SET(AUDIO_LIBRARY ${ALSA_LIBRARY}) |
159 | 190 | SET(AUDIODRV_ALSA 1) |
160 | 191 | |
161 | ELSEIF(OSS_FOUND) | |
192 | ELSEIF (OSS_FOUND) | |
162 | 193 | # no special header paths |
163 | 194 | SET(AUDIO_LIBRARY ${OSS_LIBRARY}) |
164 | 195 | SET(AUDIODRV_OSS 1) |
165 | 196 | |
166 | ELSEIF(OPENAL_FOUND) | |
197 | ELSEIF (OPENAL_FOUND) | |
167 | 198 | SET(AUDIO_LIBRARY ${OPENAL_LIBRARY}) |
168 | 199 | SET(AUDIODRV_OPENAL 1) |
169 | 200 | |
170 | ELSE() | |
201 | ELSE () | |
171 | 202 | MESSAGE(WARNING "Could not find an audio sub-system!") |
172 | 203 | SET(AUDIO_LIBRARY "") |
173 | ENDIF() | |
174 | ||
175 | ENDIF() | |
176 | ENDIF() | |
204 | ENDIF () | |
205 | ||
206 | ENDIF () | |
207 | ENDIF () | |
177 | 208 | |
178 | 209 | # find our math lib |
179 | 210 | FIND_LIBRARY(M_LIBRARY m REQUIRED) |
183 | 214 | ## Debian specific |
184 | 215 | ELSE () |
185 | 216 | ## Non debian specific |
186 | ENDIF (DPKG_PROGRAM) | |
187 | ENDIF(UNIX AND NOT APPLE) | |
188 | ||
189 | IF (APPLE AND (WANT_PLAYER OR WANT_PLAYERSTATIC)) | |
217 | ENDIF () | |
218 | ENDIF (UNIX AND NOT APPLE) | |
219 | ||
220 | IF (APPLE AND WANT_PLAYER) | |
190 | 221 | FIND_PACKAGE(OpenAL) |
191 | 222 | |
192 | IF(WANT_OPENAL) | |
193 | IF(NOT OPENAL_FOUND) | |
223 | IF (WANT_OPENAL) | |
224 | IF (NOT OPENAL_FOUND) | |
194 | 225 | MESSAGE(FATAL_ERROR "OpenAL required but not found.") |
195 | ENDIF() | |
226 | ENDIF () | |
196 | 227 | SET(AUDIO_LIBRARY ${OPENAL_LIBRARY}) |
197 | 228 | |
198 | ELSE() | |
199 | IF(OPENAL_FOUND) | |
229 | ELSE () | |
230 | IF (OPENAL_FOUND) | |
200 | 231 | SET(AUDIO_LIBRARY ${OPENAL_LIBRARY}) |
201 | 232 | SET(AUDIODRV_OPENAL 1) |
202 | 233 | |
203 | ELSE() | |
234 | ELSE () | |
204 | 235 | MESSAGE(WARNING "Could not find an audio sub-system!") |
205 | 236 | SET(AUDIO_LIBRARY "") |
206 | ENDIF() | |
207 | ||
208 | ENDIF() | |
209 | ENDIF() | |
210 | ||
211 | IF(WIN32) | |
212 | IF (WANT_PLAYER OR WANT_PLAYERSTATIC) | |
237 | ENDIF () | |
238 | ||
239 | ENDIF () | |
240 | ENDIF () | |
241 | ||
242 | IF (WIN32) | |
243 | IF (WANT_PLAYER) | |
213 | 244 | LINK_LIBRARIES(winmm) |
214 | ENDIF() | |
215 | ENDIF(WIN32) | |
245 | ENDIF () | |
246 | ENDIF (WIN32) | |
216 | 247 | |
217 | 248 | # ######### General setup ########## |
218 | 249 | INCLUDE_DIRECTORIES(BEFORE "${CMAKE_SOURCE_DIR}/include") |
219 | FILE (MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include") | |
250 | FILE(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include") | |
220 | 251 | INCLUDE_DIRECTORIES(BEFORE "${CMAKE_BINARY_DIR}/include") |
221 | IF(NOT HAVE_STDINT_H) # AND NOT HAVE_INTTYPES_H | |
222 | INCLUDE_DIRECTORIES(BEFORE "${CMAKE_SOURCE_DIR}/include/stdint") | |
223 | ENDIF() | |
224 | ||
225 | IF(APPLE) | |
252 | IF (NOT HAVE_STDINT_H) # AND NOT HAVE_INTTYPES_H | |
253 | INCLUDE_DIRECTORIES(BEFORE "${CMAKE_SOURCE_DIR}/include/stdint") | |
254 | ENDIF () | |
255 | ||
256 | IF (AMIGA OR AROS) | |
257 | SET(WILDMIDI_AMIGA 1) | |
258 | ENDIF () | |
259 | ||
260 | IF (APPLE) | |
226 | 261 | SET(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app") |
227 | 262 | SET(APP_BUNDLE_DIR "${wildmidi_BINARY_DIR}/${APP_BUNDLE_NAME}") |
228 | ENDIF(APPLE) | |
229 | ||
230 | IF(APPLE) | |
263 | IF (WANT_OSX_DEPLOYMENT) | |
264 | SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) | |
265 | ENDIF () | |
266 | ENDIF (APPLE) | |
267 | ||
268 | IF (APPLE) | |
231 | 269 | SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${APP_BUNDLE_DIR}/Contents/MacOS") |
232 | ELSE(APPLE) | |
270 | ELSE (APPLE) | |
233 | 271 | SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${wildmidi_BINARY_DIR}") |
234 | ENDIF(APPLE) | |
272 | ENDIF (APPLE) | |
235 | 273 | |
236 | 274 | # Setup up our config file |
237 | 275 | CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/include/config.h.cmake" "${CMAKE_BINARY_DIR}/include/config.h") |
5 | 5 | The library API is designed so that it is easy to include WildMIDI into |
6 | 6 | applications that wish to include MIDI file playback. |
7 | 7 | |
8 | Version: 0.4.0 | |
8 | Version: 0.4.1 | |
9 | 9 | Licenses: GPLv3+ and LGPLv3 |
10 | 10 | Website: http://www.mindwerks.net/projects/wildmidi |
11 | 11 | |
18 | 18 | * kFreeBSD: Debian (player: OSS output) |
19 | 19 | * Hurd: Debian |
20 | 20 | * DOS (player: sound blaster or compatibles output.) |
21 | * OS/2 (player: Dart output.) | |
22 | * AmigaOS & variants like MorphOS, AROS. (player: AHI output) | |
21 | 23 | |
22 | 24 | BUILD FROM SOURCE: |
23 | 25 | |
26 | 28 | * cmake |
27 | 29 | * GCC or clang / Xcode / VisualStudio / MinGW or MinGW-w64 |
28 | 30 | * DOS port: DJGPP / GNU make |
31 | * OS/2 port: OpenWatcom (tested with version 1.9) | |
32 | * Nintendo 3DS port: devkitARM | |
33 | * Nintendo Wii port: devkitPPC | |
29 | 34 | |
30 | 35 | CHANGELOG |
36 | ||
37 | 0.4.1 | |
38 | * Fixed bug in handling of the "source" directive in config files. | |
39 | * Fixed a nasty bug in dBm_pan_volume. Other fixes and clean-ups. | |
40 | * Build system updates. Install a pkg-config file on supported platforms | |
41 | such as Linux. New android ndk makefile. | |
42 | * File i/o updates. | |
43 | * Support for OS/2. | |
44 | * Support for Nintendo 3DS | |
45 | * Support for Nintendo Wii | |
46 | * Support for AmigaOS and its variants like MorphOS and AROS. | |
31 | 47 | |
32 | 48 | 0.4.0 |
33 | 49 | * API change: The library now returns audio data in host-endian format, |
49 | 65 | * API change: WildMidi_GetError() and WildMidi_ClearError() added to |
50 | 66 | cleanly check for, retrieve and clear error messages. They no longer |
51 | 67 | go to stderr. |
52 | * Support for loading XMI (XMIDI format) files, thanks Ryan Nunn for | |
53 | releasing his code under the LGPL. | |
68 | * Support for loading XMI (XMIDI format) and XFM files, such as from Arena. | |
69 | Thanks Ryan Nunn for releasing his code under the LGPL. | |
54 | 70 | * Support for loading MUS (MUS Id format) files, such as from Doom. |
55 | * Support for loading HMP/HMI files, such as from Arena and Daggerfall. | |
71 | * Support for loading HMP/HMI files, such as from Daggerfall. | |
56 | 72 | * Support for loading KAR (MIDI with Lyrics) and Type 2 MIDI files. |
57 | 73 | * Build requires cmake-2.8.11 or newer now. |
58 | 74 |
0 | # GNU Makefile to build for AmigaOS variants using gcc | |
1 | # | |
2 | # make aros : build for i386-aros | |
3 | # make morphos : build for ppc-morphos | |
4 | # make amigaos : build for m68k-amigaos | |
5 | # make amigaos4 : build for ppc-amigaos4 | |
6 | ||
7 | # Set to 1 for debug build | |
8 | DEBUG = 0 | |
9 | ||
10 | # The tools | |
11 | ifeq ($(CROSS),) | |
12 | CC=gcc | |
13 | AS=as | |
14 | AR=ar | |
15 | RANLIB=ranlib | |
16 | else | |
17 | CC=$(CROSS)-gcc | |
18 | AS=$(CROSS)-as | |
19 | AR=$(CROSS)-ar | |
20 | RANLIB=$(CROSS)-ranlib | |
21 | endif | |
22 | ||
23 | INCLUDE = -I. -I../include | |
24 | CFLAGS = $(INCLUDE) -Wall -W -fno-common | |
25 | ARFLAGS = cr | |
26 | LD = $(CC) | |
27 | LDFLAGS = -L. -lWildMidi | |
28 | ||
29 | ifeq ($(DEBUG),1) | |
30 | CFLAGS += -g | |
31 | else | |
32 | CFLAGS += -O2 | |
33 | endif | |
34 | ||
35 | ifeq ($(AROS),1) | |
36 | include gcc_aros.cfg | |
37 | endif | |
38 | ifeq ($(MORPHOS),1) | |
39 | include gcc_morphos.cfg | |
40 | endif | |
41 | ifeq ($(AOS3),1) | |
42 | include gcc_aos3.cfg | |
43 | endif | |
44 | ifeq ($(AOS4),1) | |
45 | include gcc_aos4.cfg | |
46 | endif | |
47 | ||
48 | # Build rules | |
49 | %.o: %.c | |
50 | $(CC) -c $(CFLAGS) -o $@ $< | |
51 | %.o: ../src/%.c | |
52 | $(CC) -c $(CFLAGS) -o $@ $< | |
53 | ||
54 | # Objects | |
55 | LIB_OBJ= wm_error.o file_io.o lock.o wildmidi_lib.o reverb.o gus_pat.o f_xmidi.o f_mus.o f_hmp.o f_midi.o f_hmi.o mus2mid.o xmi2mid.o internal_midi.o patches.o sample.o | |
56 | PLAYER_OBJ= getopt_long.o wm_tty.o amiga.o wildmidi.o | |
57 | ||
58 | # Build targets | |
59 | .PHONY: clean distclean | |
60 | all: libWildMidi.a wildmidi | |
61 | ||
62 | libWildMidi.a: $(LIB_OBJ) | |
63 | $(AR) $(ARFLAGS) $@ $^ | |
64 | $(RANLIB) $@ | |
65 | ||
66 | wildmidi: libWildMidi.a $(PLAYER_OBJ) | |
67 | $(LD) -o $@ $(PLAYER_OBJ) $(LDFLAGS) | |
68 | ||
69 | aros: | |
70 | @echo Building for i386-aros | |
71 | $(MAKE) AROS=1 | |
72 | morphos: | |
73 | @echo Building for ppc-morphos | |
74 | $(MAKE) MORPHOS=1 | |
75 | amigaos: | |
76 | @echo Building for m68k-amigaos | |
77 | $(MAKE) AOS3=1 | |
78 | amigaos4: | |
79 | @echo Building for ppc-amigaos4 | |
80 | $(MAKE) AOS4=1 | |
81 | ||
82 | clean: | |
83 | rm -rf $(LIB_OBJ) $(PLAYER_OBJ) | |
84 | distclean: clean | |
85 | rm -rf libWildMidi.a WildMidi.lib wildmidi |
0 | # GNU Makefile to build for AmigaOS variants using VBCC | |
1 | # | |
2 | # make amigaos : build for m68k-amigaos | |
3 | ||
4 | # for now, only tested for m68k-amigaos: | |
5 | AOS3 := 1 | |
6 | ||
7 | # The tools | |
8 | CC=vc | |
9 | #MKLIB=join $(LIB_OBJ) as WildMidi.lib | |
10 | MKLIB=cat $(LIB_OBJ) > WildMidi.lib | |
11 | ||
12 | INCLUDE = -I. -I../include | |
13 | CFLAGS = -O1 -speed -c99 | |
14 | CFLAGS += $(INCLUDE) | |
15 | LDFLAGS = -L. -lWildMidi | |
16 | ||
17 | ifeq ($(MORPHOS),1) | |
18 | include vbcc_morphos.cfg | |
19 | endif | |
20 | ifeq ($(AOS3),1) | |
21 | include vbcc_aos3.cfg | |
22 | endif | |
23 | ifeq ($(AOS4),1) | |
24 | include vbcc_aos4.cfg | |
25 | endif | |
26 | ||
27 | # Build rules | |
28 | %.o: %.c | |
29 | $(CC) -c $(CFLAGS) -o $@ $< | |
30 | %.o: ../src/%.c | |
31 | $(CC) -c $(CFLAGS) -o $@ $< | |
32 | ||
33 | # Objects | |
34 | LIB_OBJ= wm_error.o file_io.o lock.o wildmidi_lib.o reverb.o gus_pat.o f_xmidi.o f_mus.o f_hmp.o f_midi.o f_hmi.o mus2mid.o xmi2mid.o internal_midi.o patches.o sample.o | |
35 | PLAYER_OBJ= getopt_long.o wm_tty.o amiga.o wildmidi.o | |
36 | ||
37 | # Build targets | |
38 | .PHONY: clean distclean | |
39 | all: WildMidi.lib wildmidi | |
40 | ||
41 | WildMidi.lib: $(LIB_OBJ) | |
42 | $(MKLIB) | |
43 | ||
44 | wildmidi: WildMidi.lib $(PLAYER_OBJ) | |
45 | $(CC) -o $@ $(PLAYER_OBJ) $(LDFLAGS) | |
46 | ||
47 | amigaos: | |
48 | @echo Building for m68k-amigaos | |
49 | $(MAKE) -f Makefile.vbcc AOS3=1 | |
50 | amigaos4: | |
51 | @echo Building for ppc-amigaos4 | |
52 | $(MAKE) -f Makefile.vbcc AOS4=1 | |
53 | morphos: | |
54 | @echo Building for ppc-morphos | |
55 | $(MAKE) -f Makefile.vbcc MORPHOS=1 | |
56 | ||
57 | clean: | |
58 | rm -rf $(LIB_OBJ) $(PLAYER_OBJ) | |
59 | distclean: clean | |
60 | rm -rf libWildMidi.a WildMidi.lib wildmidi |
0 | /* wildmidi config for amigaos variants */ | |
1 | #define WILDMIDI_AMIGA 1 | |
2 | ||
3 | #define WILDMIDI_CFG "wildmidi.cfg" | |
4 | ||
5 | #define PACKAGE_URL "http://www.mindwerks.net/projects/wildmidi/" | |
6 | #define PACKAGE_BUGREPORT "https://github.com/Mindwerks/wildmidi/issues" | |
7 | ||
8 | #define PACKAGE_VERSION "0.4.1" | |
9 | ||
10 | #define HAVE_C_INLINE | |
11 | ||
12 | #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR >= 96)) | |
13 | #define HAVE___BUILTIN_EXPECT | |
14 | #endif | |
15 | #ifndef HAVE___BUILTIN_EXPECT | |
16 | #define __builtin_expect(x,c) x | |
17 | #endif | |
18 | ||
19 | #define AUDIODRV_AHI 1 /* AHI output for player app */ |
0 | # makefile fragment for m68k-amigaos / gcc | |
1 | ||
2 | INCLUDE+= -I../include/stdint | |
3 | LDFLAGS+= -noixemul | |
4 | LDFLAGS+= -lm | |
5 | CFLAGS += -noixemul | |
6 | CFLAGS += -DWORDS_BIGENDIAN=1 | |
7 | # avoid conflicts between our stdint.h and ixemul sys/types.h | |
8 | CFLAGS += -D_ANSI_SOURCE |
0 | # makefile fragment for ppc-amigaos4 / gcc | |
1 | ||
2 | LDFLAGS+= -noixemul | |
3 | LDFLAGS+= -lm | |
4 | CFLAGS += -noixemul | |
5 | CFLAGS += -DWORDS_BIGENDIAN=1 | |
6 | ||
7 | CFLAGS += -D__USE_INLINE__ | |
8 | CFLAGS += -D__USE_OLD_TIMEVAL__ |
0 | # makefile fragment for ppc-morphos / gcc | |
1 | ||
2 | LDFLAGS+= -noixemul | |
3 | CFLAGS += -noixemul | |
4 | CFLAGS += -DWORDS_BIGENDIAN=1 |
0 | # makefile fragment for m68k-amigaos / vbcc | |
1 | ||
2 | LDFLAGS+= -lm881 | |
3 | CFLAGS += -cpu=68020 -fpu=68881 | |
4 | CFLAGS += -D__AMIGA__ | |
5 | CFLAGS += -DWORDS_BIGENDIAN=1 | |
6 | # bullshit -- until the code is adjusted | |
7 | CFLAGS += -D__FUNCTION__=__func__ |
0 | obj/ |
0 | LOCAL_PATH := $(call my-dir) | |
1 | ||
2 | include $(CLEAR_VARS) | |
3 | LOCAL_MODULE := WildMidi_shared | |
4 | LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libWildMidi.so | |
5 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/jni $(LOCAL_PATH)/../include | |
6 | TARGET_PLATFORM = android-10 | |
7 | ||
8 | include $(PREBUILT_SHARED_LIBRARY) |
0 | LOCAL_PATH := $(call my-dir)/../.. | |
1 | include $(CLEAR_VARS) | |
2 | ||
3 | LOCAL_MODULE := WildMidi | |
4 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/android/jni $(LOCAL_PATH)/include | |
5 | LOCAL_ARM_MODE := arm | |
6 | LOCAL_CFLAGS += -DWILDMIDI_BUILD | |
7 | LOCAL_CFLAGS += -fvisibility=hidden -DSYM_VISIBILITY | |
8 | ||
9 | LOCAL_SRC_FILES := \ | |
10 | src/f_hmi.c \ | |
11 | src/f_hmp.c \ | |
12 | src/f_midi.c \ | |
13 | src/f_mus.c \ | |
14 | src/f_xmidi.c \ | |
15 | src/file_io.c \ | |
16 | src/gus_pat.c \ | |
17 | src/internal_midi.c \ | |
18 | src/lock.c \ | |
19 | src/mus2mid.c \ | |
20 | src/patches.c \ | |
21 | src/reverb.c \ | |
22 | src/sample.c \ | |
23 | src/wildmidi_lib.c \ | |
24 | src/wm_error.c \ | |
25 | src/xmi2mid.c | |
26 | ||
27 | include $(BUILD_SHARED_LIBRARY) |
0 | APP_ABI := armeabi-v7a x86 | |
1 | APP_MODULES := WildMidi | |
2 | APP_PLATFORM := android-10 | |
3 | APP_OPTIM := release | |
4 | NDK_TOOLCHAIN_VERSION := 4.9 |
0 | /* config.h -- generated from config.h.cmake */ | |
1 | ||
2 | /* Name of package */ | |
3 | #define PACKAGE "wildmidi" | |
4 | ||
5 | /* Define to the home page for this package. */ | |
6 | #define PACKAGE_URL "http://www.mindwerks.net/projects/wildmidi/" | |
7 | ||
8 | /* Define to the address where bug reports for this package should be sent. */ | |
9 | #define PACKAGE_BUGREPORT "https://github.com/Mindwerks/wildmidi/issues" | |
10 | ||
11 | /* Define to the full name of this package. */ | |
12 | #define PACKAGE_NAME "WildMidi" | |
13 | ||
14 | /* Define to the full name and version of this package. */ | |
15 | #define PACKAGE_STRING "WildMidi 0.4.1" | |
16 | ||
17 | /* Define to the one symbol short name of this package. */ | |
18 | #define PACKAGE_TARNAME "wildmidi" | |
19 | ||
20 | /* Define to the version of this package. */ | |
21 | #define PACKAGE_VERSION "0.4.1" | |
22 | ||
23 | /* Version number of package */ | |
24 | #define VERSION "0.4.1" | |
25 | ||
26 | /* Define this to the location of the wildmidi config file */ | |
27 | /* #undef WILDMIDI_CFG "/etc/wildmidi/wildmidi.cfg" */ | |
28 | ||
29 | /* Define if the C compiler supports the `inline' keyword. */ | |
30 | #define HAVE_C_INLINE | |
31 | /* Define if the C compiler supports the `__inline__' keyword. */ | |
32 | #define HAVE_C___INLINE__ | |
33 | /* Define if the C compiler supports the `__inline' keyword. */ | |
34 | #define HAVE_C___INLINE | |
35 | #if !defined(HAVE_C_INLINE) && !defined(__cplusplus) | |
36 | # ifdef HAVE_C___INLINE__ | |
37 | # define inline __inline__ | |
38 | # elif defined(HAVE_C___INLINE) | |
39 | # define inline __inline | |
40 | # else | |
41 | # define inline | |
42 | # endif | |
43 | #endif | |
44 | ||
45 | /* Define if the compiler has the `__builtin_expect' built-in function */ | |
46 | #define HAVE___BUILTIN_EXPECT | |
47 | #ifndef HAVE___BUILTIN_EXPECT | |
48 | #define __builtin_expect(x,c) x | |
49 | #endif | |
50 | ||
51 | /* define this if you are running a bigendian system (motorola, sparc, etc) */ | |
52 | /* #undef WORDS_BIGENDIAN */ | |
53 | ||
54 | /* define this if building for AmigaOS variants */ | |
55 | /* #undef WILDMIDI_AMIGA */ | |
56 | ||
57 | /* Define if you have the <stdint.h> header file. */ | |
58 | #define HAVE_STDINT_H | |
59 | ||
60 | /* Define if you have the <inttypes.h> header file. */ | |
61 | #define HAVE_INTTYPES_H | |
62 | ||
63 | /* Define our audio drivers */ | |
64 | /* #undef HAVE_LINUX_SOUNDCARD_H */ | |
65 | /* #undef HAVE_SYS_SOUNDCARD_H */ | |
66 | /* #undef HAVE_MACHINE_SOUNDCARD_H */ | |
67 | /* #undef HAVE_SOUNDCARD_H */ | |
68 | ||
69 | /* #undef AUDIODRV_ALSA */ | |
70 | /* #undef AUDIODRV_OSS */ | |
71 | /* #undef AUDIODRV_OPENAL */ | |
72 | /* #undef AUDIODRV_AHI */ |
0 | # This file is automatically generated by Android Tools. | |
1 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! | |
2 | # | |
3 | # This file must be checked in Version Control Systems. | |
4 | # | |
5 | # To customize properties used by the Ant build system use, | |
6 | # "ant.properties", and override values to adapt the script to your | |
7 | # project structure. | |
8 | ||
9 | # Project target. | |
10 | target=android-10 |
0 | version: "{build}" | |
1 | ||
2 | branches: | |
3 | only: | |
4 | - master | |
5 | - /wildmidi-.*$/ | |
6 | - appveyor | |
7 | ||
8 | platform: | |
9 | - Win32 | |
10 | - x64 | |
11 | ||
12 | configuration: Debug | |
13 | ||
14 | matrix: | |
15 | fast_finish: true | |
16 | ||
17 | # For the Qt, Boost, CMake, etc installs | |
18 | os: unstable | |
19 | ||
20 | # We want the git revision for versioning, | |
21 | # so shallow clones don't work. | |
22 | clone_depth: 1 | |
23 | ||
24 | #cache: | |
25 | # - C:\projects\wildmidi\deps\ffmpeg32-2.5.2.7z | |
26 | # - C:\projects\wildmidi\deps\ffmpeg32-2.5.2-dev.7z | |
27 | # - C:\projects\wildmidi\deps\ffmpeg64-2.5.2.7z | |
28 | # - C:\projects\wildmidi\deps\ffmpeg64-2.5.2-dev.7z | |
29 | ||
30 | clone_folder: C:\projects\wildmidi | |
31 | ||
32 | before_build: | |
33 | - cmd: sh %APPVEYOR_BUILD_FOLDER%\CI\before_script.msvc.sh -u -p %PLATFORM% | |
34 | ||
35 | build_script: | |
36 | - cmd: if %PLATFORM%==Win32 set build=Build_32 | |
37 | - cmd: if %PLATFORM%==x64 set build=Build_64 | |
38 | - cmd: msbuild %build%\WildMIDI.sln /t:Build /p:Configuration=%configuration% /m:2 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" | |
39 | ||
40 | after_build: | |
41 | - cmd: if %PLATFORM%==Win32 7z a WildMIDI_x32.zip %APPVEYOR_BUILD_FOLDER%\Build_32\Debug\wildmidi* | |
42 | - cmd: if %PLATFORM%==x64 7z a WildMIDI_x64.zip %APPVEYOR_BUILD_FOLDER%\Build_64\Debug\wildmidi* | |
43 | ||
44 | test: off | |
45 | ||
46 | #notifications: | |
47 | # - provider: Email | |
48 | # to: | |
49 | # - | |
50 | # on_build_failure: true | |
51 | # on_build_status_changed: true | |
52 | ||
53 | artifacts: | |
54 | - path: WildMIDI_x32.zip | |
55 | name: WildMIDI_x32 | |
56 | - path: WildMIDI_x64.zip | |
57 | name: WildMIDI_x64 |
2 | 2 | # You will need a DJGPP build environment and GNU make to do it painlessly. |
3 | 3 | # To build natively on DOS, you need long file names support (e.g. doslfn.) |
4 | 4 | #------------------------------------------------------------------------------# |
5 | # Targets: | |
6 | # - all (default): make libWildMidi.a library and wildmidi.exe | |
7 | # - clean: clean up (remove all generated files) | |
8 | #------------------------------------------------------------------------------# | |
9 | 5 | |
10 | 6 | # Set to 1 for debug build |
11 | 7 | DEBUG = 0 |
12 | 8 | |
13 | # Set to 1 if want to build / use a DXE3 version of the library (DJGPP-2.05 or newer) | |
14 | USE_DXE = 0 | |
9 | # DXE3 version of the library requires DJGPP-2.05 or newer. | |
10 | # Set to 0 if dont want to build / use a DXE3 version of the library. | |
11 | USE_DXE = 1 | |
15 | 12 | |
16 | 13 | # The tools |
17 | 14 | ifeq ($(CROSS),) |
2 | 2 | #define PACKAGE_URL "http://www.mindwerks.net/projects/wildmidi/" |
3 | 3 | #define PACKAGE_BUGREPORT "https://github.com/Mindwerks/wildmidi/issues" |
4 | 4 | |
5 | #define PACKAGE_VERSION "0.4.0" | |
5 | #define PACKAGE_VERSION "0.4.1" | |
6 | 6 | |
7 | 7 | #define HAVE_C_INLINE |
8 | 8 | |
13 | 13 | #define __builtin_expect(x,c) x |
14 | 14 | #endif |
15 | 15 | |
16 | #define WM_NO_LOCK 1 /* don't need locking in MSDOS */ |
23 | 23 | #ifndef __COMMON_H |
24 | 24 | #define __COMMON_H |
25 | 25 | |
26 | #ifndef __VBCC__ | |
26 | 27 | #define UNUSED(x) (void)(x) |
28 | #else | |
29 | #define UNUSED(x) /* vbcc emits an annoying warning for (void)(x) */ | |
30 | #endif | |
27 | 31 | #define MEM_CHUNK 8192 |
28 | 32 | |
29 | 33 | extern int16_t _WM_MasterVolume; |
51 | 51 | /* define this if you are running a bigendian system (motorola, sparc, etc) */ |
52 | 52 | #cmakedefine WORDS_BIGENDIAN 1 |
53 | 53 | |
54 | /* define this if building for AmigaOS variants */ | |
55 | #cmakedefine WILDMIDI_AMIGA 1 | |
56 | ||
54 | 57 | /* Define if you have the <stdint.h> header file. */ |
55 | 58 | #cmakedefine HAVE_STDINT_H |
56 | 59 | |
66 | 69 | #cmakedefine AUDIODRV_ALSA |
67 | 70 | #cmakedefine AUDIODRV_OSS |
68 | 71 | #cmakedefine AUDIODRV_OPENAL |
72 | #cmakedefine AUDIODRV_AHI |
4 | 4 | * use forward- and back-slash in path names interchangeably, and |
5 | 5 | * some of them have case-insensitive file names. |
6 | 6 | * |
7 | * Copyright 2000, 2001, 2007 Free Software Foundation, Inc. | |
7 | * This was based on filenames.h from BFD, the Binary File Descriptor | |
8 | * library, Copyright (C) 2000-2016 Free Software Foundation, Inc., | |
9 | * and changed by O. Sezer <sezero@users.sourceforge.net> for our needs. | |
10 | * The original version of this header in binutils/gcc is GPL licensed, | |
11 | * this modified version was authorized to be LGPL in our LGPL projects: | |
12 | * http://gcc.gnu.org/ml/gcc-patches/2016-09/msg02007.html | |
13 | * http://gcc.gnu.org/ml/gcc-patches/2016-09/msg02179.html | |
8 | 14 | * |
9 | * This is based on filenames.h from BFD, the Binary File Descriptor | |
10 | * library, changed further for our needs. | |
15 | * This program is free software; you can redistribute it and/or modify it | |
16 | * under the terms of the GNU Lesser General Public License as published by | |
17 | * the Free Software Foundation; either version 2.1 of the License, or (at | |
18 | * your option) any later version. | |
11 | 19 | * |
12 | * This program is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU General Public License as published by | |
14 | * the Free Software Foundation; either version 2 of the License, or | |
15 | * (at your option) any later version. | |
20 | * This program is distributed in the hope that it will be useful, but | |
21 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | |
23 | * General Public License for more details. | |
16 | 24 | * |
17 | * This program is distributed in the hope that it will be useful, | |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU General Public License for more details. | |
21 | * | |
22 | * You should have received a copy of the GNU General Public License along | |
23 | * with this program; if not, write to the Free Software Foundation, Inc., | |
24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
25 | * You should have received a copy of the GNU Lesser General Public License | |
26 | * along with this program; if not, write to the Free Software Foundation, | |
27 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
25 | 28 | */ |
26 | 29 | |
27 | 30 | #ifndef FILENAMES_H |
109 | 112 | #endif /* C++ */ |
110 | 113 | |
111 | 114 | /* ----------------- AmigaOS, MorphOS, AROS, etc: ----------------- */ |
112 | #elif defined(__MORPHOS__) || defined(__AROS__) || \ | |
113 | defined(__amigaos__) || defined(__amigaos4__) || \ | |
114 | defined(__amigados__) || defined(__AMIGA) || defined(__AMIGA__) | |
115 | #elif defined(__MORPHOS__) || defined(__AROS__) || defined(AMIGAOS) || \ | |
116 | defined(__amigaos__) || defined(__amigaos4__) || defined(__amigados__) || \ | |
117 | defined(AMIGA) || defined(_AMIGA) || defined(__AMIGA__) | |
115 | 118 | |
116 | 119 | #define HAS_DRIVE_SPEC(f) (0) /* */ |
117 | 120 | #define STRIP_DRIVE_SPEC(f) (f) /* */ |
190 | 193 | #endif |
191 | 194 | |
192 | 195 | #endif /* FILENAMES_H */ |
196 |
27 | 27 | extern void _WM_Lock (int * wmlock); |
28 | 28 | extern void _WM_Unlock (int *wmlock); |
29 | 29 | |
30 | #ifdef __DJGPP__ | |
30 | #if defined WM_NO_LOCK | |
31 | 31 | #define _WM_Lock(p) do {} while (0) |
32 | 32 | #define _WM_Unlock(p) do {} while (0) |
33 | 33 | #endif |
23 | 23 | |
24 | 24 | #include <stdint.h> |
25 | 25 | |
26 | int _WM_mus2midi (uint8_t *in, uint32_t insize, | |
26 | int _WM_mus2midi (const uint8_t *in, uint32_t insize, | |
27 | 27 | uint8_t **out, uint32_t *outsize, |
28 | 28 | uint16_t frequency); |
29 | 29 |
26 | 26 | /* library version number */ |
27 | 27 | #define LIBWILDMIDI_VER_MAJOR 0L |
28 | 28 | #define LIBWILDMIDI_VER_MINOR 4L |
29 | #define LIBWILDMIDI_VER_MICRO 0L | |
29 | #define LIBWILDMIDI_VER_MICRO 1L | |
30 | 30 | #define LIBWILDMIDI_VERSION \ |
31 | 31 | ((LIBWILDMIDI_VER_MAJOR << 16) | \ |
32 | 32 | (LIBWILDMIDI_VER_MINOR << 8) | \ |
72 | 72 | */ |
73 | 73 | # elif defined(SYM_LDSCOPE) /* __SUNPRO_C >= 0x550 */ |
74 | 74 | # define WM_SYMBOL __global |
75 | # elif defined(__OS2__) && defined(__WATCOMC__) && defined(__SW_BD) | |
76 | # define WM_SYMBOL __declspec(dllexport) | |
75 | 77 | # else |
76 | 78 | # define WM_SYMBOL |
77 | 79 | # endif |
49 | 49 | extern char * _WM_Global_ErrorS; |
50 | 50 | extern int _WM_Global_ErrorI; |
51 | 51 | |
52 | extern void _WM_GLOBAL_ERROR(const char * func, const char * file, unsigned int lne, int wmerno, const char * wmfor, int error); | |
52 | extern void _WM_GLOBAL_ERROR(const char *func, int lne, int wmerno, const char * wmfor, int error); | |
53 | 53 | |
54 | /* sets the global error string to a custom msg */ | |
54 | 55 | extern void _WM_ERROR_NEW(const char * wmfmt, ...) |
55 | 56 | #ifdef __GNUC__ |
56 | 57 | __attribute__((format(printf, 1, 2))) |
57 | 58 | #endif |
58 | 59 | ; |
59 | extern void _WM_ERROR(const char * func, unsigned int lne, int wmerno, | |
60 | const char * wmfor, int error); | |
60 | ||
61 | /* prints a debug message to stderr */ | |
62 | extern void _WM_DEBUG_MSG(const char * wmfmt, ...) | |
63 | #ifdef __GNUC__ | |
64 | __attribute__((format(printf, 1, 2))) | |
65 | #endif | |
66 | ; | |
61 | 67 | |
62 | 68 | #endif /* __WM_ERROR_H */ |
0 | /* | |
1 | * wm_tty.h - unix termios code for player | |
0 | /* wm_tty.h - unix termios code for player | |
2 | 1 | * |
3 | 2 | * Copyright (C) Chris Ison 2001-2011 |
4 | 3 | * Copyright (C) Bret Curtis 2013-2016 |
27 | 26 | void wm_inittty(void); |
28 | 27 | void wm_resetty(void); |
29 | 28 | |
30 | #if defined(_WIN32)||defined(__DJGPP__) | |
29 | #if defined(_WIN32)||defined(__DJGPP__)||defined(WILDMIDI_AMIGA)||defined(__OS2__)||defined(__EMX__) | |
31 | 30 | #define wm_inittty() do {} while (0) |
32 | 31 | #define wm_resetty() do {} while (0) |
33 | #endif /* !_WIN32, !__DJGPP__ */ | |
32 | #endif /* _WIN32, __DJGPP__, __OS2__ */ | |
34 | 33 | |
35 | 34 | #endif /* wm_tty_h */ |
34 | 34 | #define XMIDI_CONVERT_MT32_TO_GS127DRUM 0x04 /* This one is broken, don't use */ |
35 | 35 | #define XMIDI_CONVERT_GS127_TO_GS 0x05 |
36 | 36 | |
37 | int _WM_xmi2midi(uint8_t *in, uint32_t insize, | |
37 | int _WM_xmi2midi(const uint8_t *in, uint32_t insize, | |
38 | 38 | uint8_t **out, uint32_t *outsize, |
39 | 39 | uint32_t convert_type); |
40 | 40 |
0 | #define WILDMIDI_CFG "wildmidi.cfg" | |
1 | ||
2 | #define PACKAGE_URL "http://www.mindwerks.net/projects/wildmidi/" | |
3 | #define PACKAGE_BUGREPORT "https://github.com/Mindwerks/wildmidi/issues" | |
4 | ||
5 | #define PACKAGE_VERSION "0.4.1" | |
6 | ||
7 | #define HAVE_C_INLINE | |
8 | ||
9 | #if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR >= 96) | |
10 | #define HAVE___BUILTIN_EXPECT | |
11 | #endif | |
12 | #ifndef HAVE___BUILTIN_EXPECT | |
13 | #define __builtin_expect(x,c) x | |
14 | #endif | |
15 | ||
16 | #define AUDIODRV_OS2DART 1 /* OS/2 DART output */ |
0 | # Makefile for OS/2 using Watcom compiler. | |
1 | # | |
2 | # wmake | |
3 | # - builds wildmidi.dll and its import lib (wildmidi.lib) | |
4 | # | |
5 | # wmake target=static | |
6 | # - builds the static library wildmidi_static.lib | |
7 | ||
8 | !ifndef target | |
9 | target = dll | |
10 | !endif | |
11 | ||
12 | CFLAGS = -bt=os2 -bm -fp5 -fpi87 -mf -oeatxh -w4 -ei -j -zp8 -zq | |
13 | # -5s : Pentium stack calling conventions. | |
14 | # -5r : Pentium register calling conventions. | |
15 | CFLAGS+= -5s | |
16 | DLLFLAGS=-bd | |
17 | ||
18 | .SUFFIXES: | |
19 | .SUFFIXES: .obj .c | |
20 | ||
21 | DLLNAME=wildmidi.dll | |
22 | EXPNAME=wildmidi.exp | |
23 | LIBNAME=wildmidi.lib | |
24 | LIBSTATIC=wildmidi_static.lib | |
25 | PLAYER=wildmidi.exe | |
26 | PLAYER_STATIC=wildmidi_static.exe | |
27 | PLAYER_LIBS=mmpm2.lib | |
28 | ||
29 | CFLAGS_LIB= $(CFLAGS) -DWILDMIDI_BUILD | |
30 | CFLAGS_EXE= $(CFLAGS) | |
31 | !ifeq target static | |
32 | BLD_TARGET=$(LIBSTATIC) $(PLAYER_STATIC) | |
33 | !else | |
34 | CFLAGS_LIB+= $(DLLFLAGS) | |
35 | BLD_TARGET=$(DLLNAME) $(PLAYER) | |
36 | !endif | |
37 | ||
38 | OBJ=wm_error.obj file_io.obj lock.obj wildmidi_lib.obj reverb.obj gus_pat.obj f_xmidi.obj f_mus.obj f_hmp.obj f_midi.obj f_hmi.obj mus2mid.obj xmi2mid.obj internal_midi.obj patches.obj sample.obj | |
39 | PLAYER_OBJ=getopt_long.obj wm_tty.obj wildmidi.obj | |
40 | ||
41 | all: $(BLD_TARGET) | |
42 | ||
43 | # rely on symbol name, not ordinal: -irn switch of wlib is default, but -inn is not. | |
44 | $(DLLNAME): $(OBJ) | |
45 | wlink NAM $@ SYSTEM os2v2_dll INITINSTANCE TERMINSTANCE OPTION MANYAUTODATA FIL {$(OBJ)} OPTION IMPF=$(EXPNAME) | |
46 | wlib -q -b -n -inn -pa -s -t -zld -ii -io $(LIBNAME) +$(DLLNAME) | |
47 | ||
48 | $(LIBSTATIC): $(OBJ) | |
49 | wlib -q -b -n $@ $(OBJ) | |
50 | ||
51 | $(PLAYER): $(DLLNAME) $(PLAYER_OBJ) | |
52 | wlink N $@ SYS OS2V2 LIBR {$(LIBNAME) $(PLAYER_LIBS)} F {$(PLAYER_OBJ)} | |
53 | ||
54 | $(PLAYER_STATIC): $(LIBSTATIC) $(PLAYER_OBJ) | |
55 | wlink N $@ SYS OS2V2 LIBR {$(LIBSTATIC) $(PLAYER_LIBS)} F {$(PLAYER_OBJ)} | |
56 | ||
57 | # rules for library objs: | |
58 | .c.obj: | |
59 | wcc386 $(CFLAGS_LIB) $(INCLUDES) -fo=$^@ $< | |
60 | # rules for player objs: | |
61 | getopt_long.obj: getopt_long.c | |
62 | wcc386 $(CFLAGS_EXE) $(INCLUDES) -fo=$^@ $< | |
63 | wm_tty.obj: wm_tty.c | |
64 | wcc386 $(CFLAGS_EXE) $(INCLUDES) -fo=$^@ $< | |
65 | wildmidi.obj: wildmidi.c | |
66 | wcc386 $(CFLAGS_EXE) $(INCLUDES) -fo=$^@ $< | |
67 | ||
68 | !ifndef __UNIX__ | |
69 | INCLUDES=-I. -I..\include | |
70 | .c: ..\src | |
71 | distclean: clean .symbolic | |
72 | @if exist $(LIBSTATIC) del $(LIBSTATIC) | |
73 | @if exist $(DLLNAME) del $(DLLNAME) | |
74 | @if exist $(EXPNAME) del $(EXPNAME) | |
75 | @if exist $(LIBNAME) del $(LIBNAME) | |
76 | @if exist $(PLAYER) del $(PLAYER) | |
77 | @if exist $(PLAYER_STATIC) del $(PLAYER_STATIC) | |
78 | clean: .symbolic | |
79 | @if exist *.obj del *.obj | |
80 | !else | |
81 | INCLUDES=-I. -I../include | |
82 | .c: ../src | |
83 | distclean: clean .symbolic | |
84 | rm -f $(DLLNAME) $(EXPNAME) $(LIBNAME) $(LIBSTATIC) $(PLAYER) $(PLAYER_STATIC) | |
85 | clean: .symbolic | |
86 | rm -f *.obj | |
87 | !endif |
0 | # Makefile for OS/2 using EMX environment. | |
1 | # builds static wildmidi.a library and wildmidi.exe player | |
2 | ||
3 | CC=gcc | |
4 | AS=as | |
5 | AR=ar | |
6 | RANLIB=ranlib | |
7 | LD=$(CC) | |
8 | ||
9 | INCLUDES=-I. -I../include/stdint -I../include | |
10 | CFLAGS = $(INCLUDES) -Wall -W -Zmt | |
11 | LDFLAGS = -Zmt | |
12 | ARFLAGS = cr | |
13 | ||
14 | ifeq ($(DEBUG),1) | |
15 | CFLAGS += -g | |
16 | else | |
17 | CFLAGS += -O2 -ffast-math | |
18 | LDFLAGS+= -s | |
19 | endif | |
20 | ||
21 | LIBSTATIC=wildmidi.a | |
22 | PLAYER_STATIC=wildmidi.exe | |
23 | PLAYER_LIBS=-L. -lwildmidi | |
24 | #PLAYER_LIBS+=-lmmpm2 | |
25 | PLAYER_LIBS+=-los2me | |
26 | ||
27 | CFLAGS_LIB= $(CFLAGS) -DWILDMIDI_BUILD | |
28 | CFLAGS_EXE= $(CFLAGS) | |
29 | ||
30 | OBJ=wm_error.o file_io.o lock.o wildmidi_lib.o reverb.o gus_pat.o f_xmidi.o f_mus.o f_hmp.o f_midi.o f_hmi.o mus2mid.o xmi2mid.o internal_midi.o patches.o sample.o | |
31 | PLAYER_OBJ=wildmidi.o getopt_long.o wm_tty.o | |
32 | ||
33 | all: $(LIBSTATIC) $(PLAYER_STATIC) | |
34 | ||
35 | $(LIBSTATIC): $(OBJ) | |
36 | $(AR) $(ARFLAGS) $@ $^ | |
37 | -$(RANLIB) $@ | |
38 | ||
39 | $(PLAYER_STATIC): $(LIBSTATIC) $(PLAYER_OBJ) | |
40 | $(LD) -o $@ $(PLAYER_OBJ) $(PLAYER_LIBS) $(LDFLAGS) | |
41 | ||
42 | # rules for library objs: | |
43 | %.o: ../src/%.c | |
44 | $(CC) -c $(CFLAGS_LIB) -o $@ $< | |
45 | # rules for player objs: | |
46 | getopt_long.o: ../src/getopt_long.c | |
47 | $(CC) -c $(CFLAGS_EXE) -o $@ $< | |
48 | wm_tty.o: ../src/wm_tty.c | |
49 | $(CC) -c $(CFLAGS_EXE) -o $@ $< | |
50 | wildmidi.o: ../src/wildmidi.c | |
51 | $(CC) -c $(CFLAGS_EXE) -o $@ $< | |
52 | ||
53 | clean: | |
54 | $(RM) *.o | |
55 | distclean: clean | |
56 | $(RM) $(LIBSTATIC) $(PLAYER_STATIC) | |
57 |
0 | 0 | # Setup our wildmidi library that we link to |
1 | 1 | SET(wildmidi_library_SRCS |
2 | wm_error.c | |
3 | file_io.c | |
4 | lock.c | |
5 | wildmidi_lib.c | |
6 | reverb.c | |
7 | gus_pat.c | |
8 | internal_midi.c | |
9 | patches.c | |
10 | f_xmidi.c | |
11 | f_mus.c | |
12 | f_hmp.c | |
13 | f_midi.c | |
14 | f_hmi.c | |
15 | sample.c | |
16 | mus2mid.c | |
17 | xmi2mid.c | |
18 | ) | |
2 | wm_error.c | |
3 | file_io.c | |
4 | lock.c | |
5 | wildmidi_lib.c | |
6 | reverb.c | |
7 | gus_pat.c | |
8 | internal_midi.c | |
9 | patches.c | |
10 | f_xmidi.c | |
11 | f_mus.c | |
12 | f_hmp.c | |
13 | f_midi.c | |
14 | f_hmi.c | |
15 | sample.c | |
16 | mus2mid.c | |
17 | xmi2mid.c | |
18 | ) | |
19 | 19 | |
20 | 20 | SET(wildmidi_library_HDRS |
21 | ../include/wm_error.h | |
22 | ../include/file_io.h | |
23 | ../include/lock.h | |
24 | ../include/wildmidi_lib.h | |
25 | ../include/reverb.h | |
26 | ../include/gus_pat.h | |
27 | ../include/f_xmidi.h | |
28 | ../include/f_mus.h | |
29 | ../include/f_hmp.h | |
30 | ../include/f_midi.h | |
31 | ../include/f_hmi.h | |
32 | ../include/internal_midi.h | |
33 | ../include/patches.h | |
34 | ../include/sample.h | |
35 | ../include/common.h | |
36 | ../include/filenames.h | |
37 | ../include/mus2mid.h | |
38 | ../include/xmi2mid.h | |
39 | ) | |
40 | ||
41 | IF(MSVC) | |
42 | SET(GETOPT getopt_long.c) | |
43 | ELSE() | |
44 | SET(GETOPT) | |
45 | ENDIF() | |
21 | ../include/wm_error.h | |
22 | ../include/file_io.h | |
23 | ../include/lock.h | |
24 | ../include/wildmidi_lib.h | |
25 | ../include/reverb.h | |
26 | ../include/gus_pat.h | |
27 | ../include/f_xmidi.h | |
28 | ../include/f_mus.h | |
29 | ../include/f_hmp.h | |
30 | ../include/f_midi.h | |
31 | ../include/f_hmi.h | |
32 | ../include/internal_midi.h | |
33 | ../include/patches.h | |
34 | ../include/sample.h | |
35 | ../include/common.h | |
36 | ../include/filenames.h | |
37 | ../include/mus2mid.h | |
38 | ../include/xmi2mid.h | |
39 | ) | |
40 | ||
41 | IF (MSVC) | |
42 | SET(GETOPT getopt_long.c) | |
43 | ELSE () | |
44 | SET(GETOPT) | |
45 | ENDIF () | |
46 | ||
47 | IF (AMIGA OR AROS) | |
48 | SET(SYS_OTHER amiga.c) | |
49 | ELSE () | |
50 | SET(SYS_OTHER) | |
51 | ENDIF () | |
52 | ||
46 | 53 | SET(wildmidi_executable_SRCS |
47 | ${GETOPT} | |
48 | wm_tty.c | |
49 | wildmidi.c | |
50 | ) | |
54 | ${GETOPT} | |
55 | ${SYS_OTHER} | |
56 | wm_tty.c | |
57 | wildmidi.c | |
58 | ) | |
51 | 59 | |
52 | 60 | SET(wildmidi_executable_HDRS |
53 | ../include/wm_tty.h | |
54 | ../include/getopt_long.h | |
55 | ) | |
61 | ../include/wm_tty.h | |
62 | ../include/getopt_long.h | |
63 | ) | |
56 | 64 | |
57 | 65 | # set our target paths |
58 | 66 | SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}") |
59 | 67 | SET(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}") |
60 | 68 | |
61 | 69 | # set our library names |
62 | IF(WIN32 AND NOT CMAKE_COMPILER_IS_MINGW) # windows uses *.lib for both static and dynamic, workaround | |
70 | IF (WIN32 AND NOT CMAKE_COMPILER_IS_MINGW) # windows uses *.lib for both static and dynamic, workaround | |
63 | 71 | SET(LIBRARY_DYN_NAME "wildmidi_dynamic") |
64 | 72 | SET(LIBRARY_STATIC_NAME "wildmidi_static") |
65 | ELSE() # everyone else uses .a and .so | |
73 | ELSE () # everyone else uses .a and .so | |
66 | 74 | SET(LIBRARY_DYN_NAME "WildMidi") |
67 | 75 | SET(LIBRARY_STATIC_NAME "WildMidi") |
68 | ENDIF() | |
76 | ENDIF () | |
69 | 77 | |
70 | 78 | # do we want a static library? |
71 | IF(WANT_STATIC) | |
79 | IF (WANT_STATIC) | |
72 | 80 | ADD_LIBRARY(libwildmidi_static STATIC |
73 | ${wildmidi_library_SRCS} | |
74 | ${wildmidi_library_HDRS} | |
75 | ) | |
81 | ${wildmidi_library_SRCS} | |
82 | ${wildmidi_library_HDRS} | |
83 | ) | |
76 | 84 | |
77 | 85 | TARGET_LINK_LIBRARIES(libwildmidi_static |
78 | ${M_LIBRARY} | |
79 | ) | |
86 | ${M_LIBRARY} | |
87 | ) | |
80 | 88 | |
81 | 89 | SET_TARGET_PROPERTIES(libwildmidi_static PROPERTIES |
82 | OUTPUT_NAME ${LIBRARY_STATIC_NAME} CLEAN_DIRECT_OUTPUT 1 | |
83 | COMPILE_DEFINITIONS WILDMIDI_BUILD | |
84 | ) | |
85 | ENDIF(WANT_STATIC) | |
86 | ||
87 | # always build our dynamic library | |
88 | ADD_LIBRARY(libwildmidi_dynamic SHARED | |
89 | ${wildmidi_library_SRCS} | |
90 | ${wildmidi_library_HDRS} | |
91 | ) | |
92 | ||
93 | TARGET_LINK_LIBRARIES(libwildmidi_dynamic | |
94 | ${M_LIBRARY} | |
95 | ) | |
96 | ||
97 | SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
98 | SOVERSION ${SOVERSION} | |
99 | VERSION ${VERSION} | |
100 | OUTPUT_NAME ${LIBRARY_DYN_NAME} CLEAN_DIRECT_OUTPUT 1 | |
101 | ) | |
102 | ||
103 | IF(WIN32) | |
90 | OUTPUT_NAME ${LIBRARY_STATIC_NAME} CLEAN_DIRECT_OUTPUT 1 | |
91 | COMPILE_DEFINITIONS WILDMIDI_BUILD | |
92 | ) | |
93 | ENDIF (WANT_STATIC) | |
94 | ||
95 | IF (BUILD_SHARED_LIBS) | |
96 | # dynamic library | |
97 | ADD_LIBRARY(libwildmidi_dynamic SHARED | |
98 | ${wildmidi_library_SRCS} | |
99 | ${wildmidi_library_HDRS} | |
100 | ) | |
101 | ||
102 | TARGET_LINK_LIBRARIES(libwildmidi_dynamic | |
103 | ${M_LIBRARY} | |
104 | ) | |
105 | ||
104 | 106 | SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES |
105 | DEFINE_SYMBOL DLL_EXPORT | |
106 | COMPILE_DEFINITIONS WILDMIDI_BUILD | |
107 | ) | |
108 | ELSEIF(HAVE_VISIBILITY_HIDDEN AND HAVE_VISIBILITY_DEFAULT) # GCC, Clang | |
109 | SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
110 | COMPILE_DEFINITIONS "WILDMIDI_BUILD;SYM_VISIBILITY" | |
111 | COMPILE_FLAGS "-fvisibility=hidden" | |
112 | ) | |
113 | #ELSEIF(HAVE_LDSCOPE_HIDDEN AND HAVE_VISIBILITY_DEFAULT) # SunPro (__SUNPRO_C >= 0x590) | |
114 | # SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
115 | # COMPILE_DEFINITIONS "WILDMIDI_BUILD;SYM_VISIBILITY" | |
116 | # COMPILE_FLAGS "-xldscope=hidden" | |
117 | # ) | |
118 | ELSEIF(HAVE_LDSCOPE_HIDDEN AND HAVE_LDSCOPE_GLOBAL) # SunPro (__SUNPRO_C >= 0x550) | |
119 | SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
120 | COMPILE_DEFINITIONS "WILDMIDI_BUILD;SYM_LDSCOPE" | |
121 | COMPILE_FLAGS "-xldscope=hidden" | |
122 | ) | |
123 | ELSE() | |
124 | SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
125 | COMPILE_DEFINITIONS WILDMIDI_BUILD | |
126 | ) | |
127 | ENDIF() | |
107 | SOVERSION ${SOVERSION} | |
108 | VERSION ${VERSION} | |
109 | OUTPUT_NAME ${LIBRARY_DYN_NAME} CLEAN_DIRECT_OUTPUT 1 | |
110 | ) | |
111 | ||
112 | IF (WIN32) | |
113 | SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
114 | DEFINE_SYMBOL DLL_EXPORT | |
115 | COMPILE_DEFINITIONS WILDMIDI_BUILD | |
116 | ) | |
117 | ELSEIF (HAVE_VISIBILITY_HIDDEN AND HAVE_VISIBILITY_DEFAULT) # GCC, Clang | |
118 | SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
119 | COMPILE_DEFINITIONS "WILDMIDI_BUILD;SYM_VISIBILITY" | |
120 | COMPILE_FLAGS "-fvisibility=hidden" | |
121 | ) | |
122 | #ELSEIF (HAVE_LDSCOPE_HIDDEN AND HAVE_VISIBILITY_DEFAULT) # SunPro (__SUNPRO_C >= 0x590) | |
123 | # SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
124 | # COMPILE_DEFINITIONS "WILDMIDI_BUILD;SYM_VISIBILITY" | |
125 | # COMPILE_FLAGS "-xldscope=hidden" | |
126 | # ) | |
127 | ELSEIF (HAVE_LDSCOPE_HIDDEN AND HAVE_LDSCOPE_GLOBAL) # SunPro (__SUNPRO_C >= 0x550) | |
128 | SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
129 | COMPILE_DEFINITIONS "WILDMIDI_BUILD;SYM_LDSCOPE" | |
130 | COMPILE_FLAGS "-xldscope=hidden" | |
131 | ) | |
132 | ELSE () | |
133 | SET_TARGET_PROPERTIES(libwildmidi_dynamic PROPERTIES | |
134 | COMPILE_DEFINITIONS WILDMIDI_BUILD | |
135 | ) | |
136 | ENDIF () | |
137 | ENDIF (BUILD_SHARED_LIBS) | |
128 | 138 | |
129 | 139 | # Set our default and then look at the possible locations |
130 | 140 | SET(WILDMIDILIB "${CMAKE_BINARY_DIR}/lib${LIBRARY_DYN_NAME}.so") |
131 | 141 | SET(WILDMIDILIBSTATIC "${CMAKE_BINARY_DIR}/lib${LIBRARY_STATIC_NAME}.a") |
132 | 142 | |
133 | 143 | # MS Visual Studio |
134 | IF(MSVC) | |
144 | IF (MSVC) | |
135 | 145 | SET(WILDMIDILIB "${CMAKE_BINARY_DIR}\\${CMAKE_BUILD_TYPE}\\${LIBRARY_DYN_NAME}.lib") |
136 | 146 | SET(WILDMIDILIBSTATIC "${CMAKE_BINARY_DIR}\\${CMAKE_BUILD_TYPE}\\${LIBRARY_STATIC_NAME}.lib") |
137 | ENDIF(MSVC) | |
147 | ENDIF (MSVC) | |
138 | 148 | |
139 | 149 | # MinGW or MinGW-w64 |
140 | IF(CMAKE_COMPILER_IS_MINGW) | |
150 | IF (CMAKE_COMPILER_IS_MINGW) | |
141 | 151 | SET(WILDMIDILIB "${CMAKE_BINARY_DIR}/lib${LIBRARY_DYN_NAME}.dll.a") |
142 | 152 | SET(WILDMIDIDLL "${CMAKE_BINARY_DIR}/lib${LIBRARY_DYN_NAME}.dll") |
143 | 153 | SET(WILDMIDILIBSTATIC "${CMAKE_BINARY_DIR}/lib${LIBRARY_STATIC_NAME}.a") |
144 | ENDIF(CMAKE_COMPILER_IS_MINGW) | |
154 | ENDIF (CMAKE_COMPILER_IS_MINGW) | |
145 | 155 | |
146 | 156 | # Apple's Xcode |
147 | IF(CMAKE_GENERATOR STREQUAL "Xcode") | |
157 | IF (CMAKE_GENERATOR STREQUAL "Xcode") | |
148 | 158 | SET(WILDMIDILIB "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/lib${LIBRARY_DYN_NAME}.dylib") |
149 | 159 | SET(WILDMIDILIBSTATIC "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/lib${LIBRARY_STATIC_NAME}.a") |
150 | ELSEIF(APPLE) # Apple's CLI default | |
160 | ELSEIF (APPLE) # Apple's CLI default | |
151 | 161 | SET(WILDMIDILIB "${CMAKE_BINARY_DIR}/lib${LIBRARY_DYN_NAME}.dylib") |
152 | 162 | SET(WILDMIDILIBSTATIC "${CMAKE_BINARY_DIR}/lib${LIBRARY_STATIC_NAME}.a") |
153 | ENDIF(CMAKE_GENERATOR STREQUAL "Xcode") | |
163 | ENDIF (CMAKE_GENERATOR STREQUAL "Xcode") | |
154 | 164 | |
155 | 165 | # do we want the wildmidi player? |
156 | IF(WANT_PLAYER) | |
166 | IF (WANT_PLAYER AND BUILD_SHARED_LIBS) | |
157 | 167 | ADD_EXECUTABLE(wildmidi |
158 | ${wildmidi_executable_SRCS} | |
159 | ${wildmidi_executable_HDRS} | |
160 | ) | |
168 | ${wildmidi_executable_SRCS} | |
169 | ${wildmidi_executable_HDRS} | |
170 | ) | |
161 | 171 | |
162 | 172 | ADD_DEPENDENCIES(wildmidi libwildmidi_dynamic) |
163 | 173 | |
164 | IF(AUDIODRV_OPENAL) | |
165 | TARGET_INCLUDE_DIRECTORIES(wildmidi PRIVATE | |
166 | ${OPENAL_INCLUDE_DIR} | |
167 | ) | |
168 | ELSEIF(AUDIODRV_ALSA) | |
169 | TARGET_INCLUDE_DIRECTORIES(wildmidi PRIVATE | |
170 | ${ALSA_INCLUDE_DIR} | |
171 | ) | |
172 | ELSEIF(AUDIODRV_OSS) | |
173 | # no special header paths | |
174 | ENDIF() | |
174 | IF (AUDIODRV_OPENAL) | |
175 | TARGET_INCLUDE_DIRECTORIES(wildmidi PRIVATE | |
176 | ${OPENAL_INCLUDE_DIR} | |
177 | ) | |
178 | ELSEIF (AUDIODRV_ALSA) | |
179 | TARGET_INCLUDE_DIRECTORIES(wildmidi PRIVATE | |
180 | ${ALSA_INCLUDE_DIR} | |
181 | ) | |
182 | ELSEIF (AUDIODRV_OSS) | |
183 | # no special header paths | |
184 | ENDIF () | |
175 | 185 | |
176 | 186 | TARGET_LINK_LIBRARIES(wildmidi |
177 | ${WILDMIDILIB} | |
178 | ${M_LIBRARY} | |
179 | ${AUDIO_LIBRARY} | |
180 | ) | |
181 | ENDIF(WANT_PLAYER) | |
182 | ||
183 | IF(WANT_PLAYERSTATIC) | |
187 | ${WILDMIDILIB} | |
188 | ${M_LIBRARY} | |
189 | ${AUDIO_LIBRARY} | |
190 | ) | |
191 | ENDIF () | |
192 | ||
193 | IF (WANT_PLAYERSTATIC) | |
184 | 194 | ADD_EXECUTABLE(wildmidi-static |
185 | ${wildmidi_executable_SRCS} | |
186 | ${wildmidi_executable_HDRS} | |
187 | ) | |
195 | ${wildmidi_executable_SRCS} | |
196 | ${wildmidi_executable_HDRS} | |
197 | ) | |
188 | 198 | |
189 | 199 | ADD_DEPENDENCIES(wildmidi-static libwildmidi_static) |
190 | 200 | |
191 | 201 | SET_TARGET_PROPERTIES(wildmidi-static PROPERTIES |
192 | COMPILE_DEFINITIONS WILDMIDI_STATIC | |
193 | ) | |
194 | ||
195 | IF(AUDIODRV_OPENAL) | |
196 | TARGET_INCLUDE_DIRECTORIES(wildmidi-static PRIVATE | |
197 | ${OPENAL_INCLUDE_DIR} | |
198 | ) | |
199 | ELSEIF(AUDIODRV_ALSA) | |
200 | TARGET_INCLUDE_DIRECTORIES(wildmidi-static PRIVATE | |
201 | ${ALSA_INCLUDE_DIR} | |
202 | ) | |
203 | ELSEIF(AUDIODRV_OSS) | |
204 | # no special header paths | |
205 | ENDIF() | |
202 | COMPILE_DEFINITIONS WILDMIDI_STATIC | |
203 | ) | |
204 | ||
205 | IF (AUDIODRV_OPENAL) | |
206 | TARGET_INCLUDE_DIRECTORIES(wildmidi-static PRIVATE | |
207 | ${OPENAL_INCLUDE_DIR} | |
208 | ) | |
209 | ELSEIF (AUDIODRV_ALSA) | |
210 | TARGET_INCLUDE_DIRECTORIES(wildmidi-static PRIVATE | |
211 | ${ALSA_INCLUDE_DIR} | |
212 | ) | |
213 | ELSEIF (AUDIODRV_OSS) | |
214 | # no special header paths | |
215 | ENDIF () | |
206 | 216 | |
207 | 217 | TARGET_LINK_LIBRARIES(wildmidi-static |
208 | ${WILDMIDILIBSTATIC} | |
209 | ${M_LIBRARY} | |
210 | ${AUDIO_LIBRARY} | |
211 | ) | |
212 | ENDIF(WANT_PLAYERSTATIC) | |
213 | ||
214 | IF(WANT_DEVTEST) | |
218 | ${WILDMIDILIBSTATIC} | |
219 | ${M_LIBRARY} | |
220 | ${AUDIO_LIBRARY} | |
221 | ) | |
222 | ENDIF (WANT_PLAYERSTATIC) | |
223 | ||
224 | IF (WANT_DEVTEST) | |
215 | 225 | SET(wildmidi-devtest_executable_SRCS |
216 | ${GETOPT} | |
217 | DevTest.c | |
218 | ) | |
226 | ${GETOPT} | |
227 | DevTest.c | |
228 | ) | |
219 | 229 | ADD_EXECUTABLE(wildmidi-devtest |
220 | ${wildmidi-devtest_executable_SRCS} | |
221 | ) | |
222 | ENDIF(WANT_DEVTEST) | |
230 | ${wildmidi-devtest_executable_SRCS} | |
231 | ) | |
232 | ENDIF (WANT_DEVTEST) | |
233 | ||
234 | # convenience variables | |
235 | SET(WILDMIDILIB_INSTALLDIR "lib${LIB_SUFFIX}") | |
236 | SET(WILDMIDIDLL_INSTALLDIR "bin${LIB_SUFFIX}") | |
237 | ||
238 | # add multiarch folder, if needed | |
239 | IF (CMAKE_LIBRARY_ARCHITECTURE) | |
240 | SET(WILDMIDILIB_INSTALLDIR "${WILDMIDILIB_INSTALLDIR}/${CMAKE_LIBRARY_ARCHITECTURE}") | |
241 | SET(WILDMIDIDLL_INSTALLDIR "${WILDMIDIDLL_INSTALLDIR}/${CMAKE_LIBRARY_ARCHITECTURE}") | |
242 | ENDIF () | |
243 | ||
244 | # prepare pkg-config file | |
245 | SET(WILDMIDILIB_PREFIX "${CMAKE_INSTALL_PREFIX}") | |
246 | SET(WILDMIDILIB_LIBDIR "${WILDMIDILIB_INSTALLDIR}") | |
247 | CONFIGURE_FILE("wildmidi.pc.in" "${CMAKE_BINARY_DIR}/wildmidi.pc" @ONLY) | |
223 | 248 | |
224 | 249 | # install target (*nix OSes) |
225 | IF(UNIX AND NOT APPLE) | |
250 | IF (UNIX AND NOT APPLE) | |
226 | 251 | # install our libraries |
227 | IF(WANT_STATIC) | |
228 | INSTALL(TARGETS libwildmidi_static DESTINATION "lib${LIB_SUFFIX}/${CMAKE_LIBRARY_ARCHITECTURE}") | |
229 | ENDIF(WANT_STATIC) | |
230 | INSTALL(TARGETS libwildmidi_dynamic DESTINATION "lib${LIB_SUFFIX}/${CMAKE_LIBRARY_ARCHITECTURE}") | |
231 | ||
232 | # install our player if asked for | |
233 | IF(WANT_PLAYER) | |
234 | INSTALL(TARGETS wildmidi DESTINATION bin) | |
235 | ENDIF(WANT_PLAYER) | |
236 | IF(WANT_PLAYERSTATIC) | |
237 | INSTALL(TARGETS wildmidi-static DESTINATION bin) | |
238 | ENDIF(WANT_PLAYERSTATIC) | |
252 | IF (WANT_STATIC) | |
253 | INSTALL(TARGETS libwildmidi_static DESTINATION ${WILDMIDILIB_INSTALLDIR}) | |
254 | IF (WANT_PLAYERSTATIC) | |
255 | INSTALL(TARGETS wildmidi-static DESTINATION bin) | |
256 | ENDIF () | |
257 | ENDIF (WANT_STATIC) | |
258 | ||
259 | IF (BUILD_SHARED_LIBS) | |
260 | INSTALL(TARGETS libwildmidi_dynamic DESTINATION ${WILDMIDILIB_INSTALLDIR}) | |
261 | IF (WANT_PLAYER) | |
262 | INSTALL(TARGETS wildmidi DESTINATION bin) | |
263 | ENDIF () | |
264 | ENDIF () | |
239 | 265 | |
240 | 266 | # install our devtest if asked for |
241 | IF(WANT_DEVTEST) | |
267 | IF (WANT_DEVTEST) | |
242 | 268 | INSTALL(TARGETS wildmidi-devtest DESTINATION bin) |
243 | ENDIF(WANT_DEVTEST) | |
269 | ENDIF (WANT_DEVTEST) | |
270 | ||
271 | # install pkg-config file | |
272 | INSTALL(FILES ${CMAKE_BINARY_DIR}/wildmidi.pc DESTINATION "${WILDMIDILIB_INSTALLDIR}/pkgconfig") | |
244 | 273 | |
245 | 274 | # install supporting man pages and headers |
246 | 275 | INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/wildmidi_lib.h DESTINATION include) |
247 | 276 | INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/docs/man/ DESTINATION share/man) |
248 | ENDIF(UNIX AND NOT APPLE) | |
277 | ENDIF (UNIX AND NOT APPLE) | |
249 | 278 | |
250 | 279 | # install target (Windows: MinGW or MinGW-w64) |
251 | IF(WIN32 AND CMAKE_COMPILER_IS_MINGW) | |
252 | IF("${CMAKE_INSTALL_PREFIX}" STREQUAL "") | |
280 | IF (WIN32 AND CMAKE_COMPILER_IS_MINGW) | |
281 | IF ("${CMAKE_INSTALL_PREFIX}" STREQUAL "") | |
253 | 282 | MESSAGE("INSTALL PREFIX IS EMPTY") |
254 | 283 | SET(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/wildmidi_lib" CACHE STRING "Install Prefix" FORCE) |
255 | 284 | MESSAGE("INSTALL PREFIX NOW: ${CMAKE_INSTALL_PREFIX}") |
256 | ENDIF("${CMAKE_INSTALL_PREFIX}" STREQUAL "" ) | |
285 | ENDIF ("${CMAKE_INSTALL_PREFIX}" STREQUAL "") | |
257 | 286 | # install our libraries |
258 | IF(WANT_STATIC) | |
259 | INSTALL(TARGETS libwildmidi_static DESTINATION "lib${LIB_SUFFIX}/${CMAKE_LIBRARY_ARCHITECTURE}") | |
260 | ENDIF(WANT_STATIC) | |
261 | INSTALL(FILES ${WILDMIDILIB} DESTINATION "lib${LIB_SUFFIX}/${CMAKE_LIBRARY_ARCHITECTURE}") | |
262 | INSTALL(FILES ${WILDMIDIDLL} DESTINATION "bin${LIB_SUFFIX}/${CMAKE_LIBRARY_ARCHITECTURE}") | |
263 | ||
264 | # install our player if asked for | |
265 | IF(WANT_PLAYER) | |
266 | INSTALL(TARGETS wildmidi DESTINATION bin) | |
267 | ENDIF(WANT_PLAYER) | |
268 | IF(WANT_PLAYERSTATIC) | |
269 | INSTALL(TARGETS wildmidi-static DESTINATION bin) | |
270 | ENDIF(WANT_PLAYERSTATIC) | |
287 | IF (WANT_STATIC) | |
288 | INSTALL(TARGETS libwildmidi_static DESTINATION ${WILDMIDILIB_INSTALLDIR}) | |
289 | IF (WANT_PLAYERSTATIC) | |
290 | INSTALL(TARGETS wildmidi-static DESTINATION bin) | |
291 | ENDIF () | |
292 | ENDIF (WANT_STATIC) | |
293 | IF (BUILD_SHARED_LIBS) | |
294 | INSTALL(FILES ${WILDMIDILIB} DESTINATION ${WILDMIDILIB_INSTALLDIR}) | |
295 | INSTALL(FILES ${WILDMIDIDLL} DESTINATION ${WILDMIDIDLL_INSTALLDIR}) | |
296 | IF (WANT_PLAYER) | |
297 | INSTALL(TARGETS wildmidi DESTINATION bin) | |
298 | ENDIF () | |
299 | ENDIF () | |
271 | 300 | |
272 | 301 | # install our devtest if asked for |
273 | IF(WANT_DEVTEST) | |
302 | IF (WANT_DEVTEST) | |
274 | 303 | INSTALL(TARGETS wildmidi-devtest DESTINATION bin) |
275 | ENDIF(WANT_DEVTEST) | |
304 | ENDIF (WANT_DEVTEST) | |
305 | ||
306 | # install pkg-config file | |
307 | INSTALL(FILES ${CMAKE_BINARY_DIR}/wildmidi.pc DESTINATION "${WILDMIDILIB_INSTALLDIR}/pkgconfig") | |
276 | 308 | |
277 | 309 | # install supporting man pages and headers |
278 | 310 | INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/wildmidi_lib.h DESTINATION include) |
279 | 311 | INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/docs/man/ DESTINATION share/man) |
280 | ENDIF(WIN32 AND CMAKE_COMPILER_IS_MINGW) | |
312 | ENDIF (WIN32 AND CMAKE_COMPILER_IS_MINGW) | |
313 | ||
314 | IF (WIN32 AND MSVC) | |
315 | IF (WANT_MP_BUILD) | |
316 | SET(MT_BUILD "/MP") | |
317 | ENDIF () | |
318 | ||
319 | foreach (OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) | |
320 | STRING(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) | |
321 | SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(SolutionDir)$(Configuration)") | |
322 | SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(ProjectDir)$(Configuration)") | |
323 | endforeach (OUTPUTCONFIG) | |
324 | ||
325 | IF (WANT_PLAYER) | |
326 | # Release builds use the debug console | |
327 | SET_TARGET_PROPERTIES(wildmidi PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE") | |
328 | SET_TARGET_PROPERTIES(wildmidi PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE") | |
329 | TARGET_COMPILE_DEFINITIONS(wildmidi PRIVATE $<$<CONFIG:Release>:_CONSOLE>) | |
330 | TARGET_COMPILE_DEFINITIONS(wildmidi PRIVATE $<$<CONFIG:MinSizeRel>:_CONSOLE>) | |
331 | ENDIF () | |
332 | ||
333 | IF (WANT_PLAYERSTATIC) | |
334 | # Release builds use the debug console | |
335 | SET_TARGET_PROPERTIES(wildmidi-static PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE") | |
336 | SET_TARGET_PROPERTIES(wildmidi-static PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE") | |
337 | TARGET_COMPILE_DEFINITIONS(wildmidi-static PRIVATE $<$<CONFIG:Release>:_CONSOLE>) | |
338 | TARGET_COMPILE_DEFINITIONS(wildmidi-static PRIVATE $<$<CONFIG:MinSizeRel>:_CONSOLE>) | |
339 | ENDIF () | |
340 | ||
341 | # Play a bit with the warning levels | |
342 | ||
343 | SET(WARNINGS "/Wall") # Since windows can only disable specific warnings, not enable them | |
344 | ||
345 | SET(WARNINGS_DISABLE | |
346 | # Warnings that aren't enabled normally and don't need to be enabled | |
347 | # They're unneeded and sometimes completely retarded warnings that /Wall enables | |
348 | # Not going to bother commenting them as they tend to warn on every standard library file | |
349 | 4061 4263 4264 4266 4350 4371 4435 4514 4548 4571 4610 4619 4623 4625 4626 4628 4640 4668 4710 4711 4820 4826 4917 4946 | |
350 | ||
351 | # Warnings that are thrown on standard libraries | |
352 | 4347 # Non-template function with same name and parameter count as template function | |
353 | 4365 # Variable signed/unsigned mismatch | |
354 | 4510 4512 # Unable to generate copy constructor/assignment operator as it's not public in the base | |
355 | 4706 # Assignment in conditional expression | |
356 | 4738 # Storing 32-bit float result in memory, possible loss of performance | |
357 | 4986 # Undocumented warning that occurs in the crtdbg.h file | |
358 | 4987 # nonstandard extension used (triggered by setjmp.h) | |
359 | 4996 # Function was declared deprecated | |
360 | ||
361 | # caused by boost | |
362 | 4191 # 'type cast' : unsafe conversion (1.56, thread_primitives.hpp, normally off) | |
363 | ||
364 | # project specific warnings | |
365 | 4099 # Type mismatch, declared class or struct is defined with other type | |
366 | 4100 # Unreferenced formal parameter (-Wunused-parameter) | |
367 | 4101 # Unreferenced local variable (-Wunused-variable) | |
368 | 4127 # Conditional expression is constant | |
369 | 4242 # Storing value in a variable of a smaller type, possible loss of data | |
370 | 4244 # Storing value of one type in variable of another (size_t in int, for example) | |
371 | 4245 # Signed/unsigned mismatch | |
372 | 4267 # Conversion from 'size_t' to 'int', possible loss of data | |
373 | 4305 # Truncating value (double to float, for example) | |
374 | 4309 # Variable overflow, trying to store 128 in a signed char for example | |
375 | 4351 # New behavior: elements of array 'array' will be default initialized (desired behavior) | |
376 | 4355 # Using 'this' in member initialization list | |
377 | 4505 # Unreferenced local function has been removed | |
378 | 4701 # Potentially uninitialized local variable used | |
379 | 4702 # Unreachable code | |
380 | 4800 # Boolean optimization warning, e.g. myBool = (myInt != 0) instead of myBool = myInt | |
381 | ) | |
382 | ||
383 | foreach (d ${WARNINGS_DISABLE}) | |
384 | SET(WARNINGS "${WARNINGS} /wd${d}") | |
385 | endforeach (d) | |
386 | ||
387 | IF (WANT_PLAYER) | |
388 | SET_TARGET_PROPERTIES(wildmidi PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") | |
389 | ENDIF () | |
390 | ||
391 | IF (WANT_PLAYERSTATIC) | |
392 | SET_TARGET_PROPERTIES(wildmidi-static PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") | |
393 | ENDIF () | |
394 | ||
395 | ENDIF () |
1564 | 1564 | } |
1565 | 1565 | |
1566 | 1566 | if (strncmp((char *) midi_data, "MThd", 4) != 0) { |
1567 | printf("Not a compatable file\n"); | |
1567 | printf("Not a compatible file\n"); | |
1568 | 1568 | return -1; |
1569 | 1569 | } |
1570 | 1570 |
0 | /* amiga-specific stuff for WildMIDI player | |
1 | * Copyright (C) WildMIDI Developers 2016 | |
2 | * | |
3 | * WildMIDI is free software: you can redistribute and/or modify the player | |
4 | * under the terms of the GNU General Public License and you can redistribute | |
5 | * and/or modify the library under the terms of the GNU Lesser General Public | |
6 | * License as published by the Free Software Foundation, either version 3 of | |
7 | * the licenses, or(at your option) any later version. | |
8 | * | |
9 | * WildMIDI is distributed in the hope that it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License and | |
12 | * the GNU Lesser General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License and the | |
15 | * GNU Lesser General Public License along with WildMIDI. If not, see | |
16 | * <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
19 | #include <proto/exec.h> | |
20 | #include <proto/dos.h> | |
21 | #include <proto/timer.h> | |
22 | ||
23 | #include <stdio.h> | |
24 | #include <stdlib.h> | |
25 | ||
26 | struct timerequest *timerio; | |
27 | struct MsgPort *timerport; | |
28 | #if defined(__MORPHOS__) || defined(__VBCC__) | |
29 | struct Library *TimerBase; | |
30 | #else | |
31 | struct Device *TimerBase; | |
32 | #endif | |
33 | ||
34 | static BPTR amiga_stdin, amiga_stdout; | |
35 | #define MODE_RAW 1 | |
36 | #define MODE_NORMAL 0 | |
37 | ||
38 | static void amiga_atexit (void) { | |
39 | if (amiga_stdin) | |
40 | SetMode(amiga_stdin, MODE_NORMAL); | |
41 | if (TimerBase) { | |
42 | WaitIO((struct IORequest *) timerio); | |
43 | CloseDevice((struct IORequest *) timerio); | |
44 | DeleteIORequest((struct IORequest *) timerio); | |
45 | DeleteMsgPort(timerport); | |
46 | TimerBase = NULL; | |
47 | } | |
48 | } | |
49 | ||
50 | void amiga_sysinit (void) { | |
51 | if ((timerport = CreateMsgPort())) { | |
52 | if ((timerio = (struct timerequest *)CreateIORequest(timerport, sizeof(struct timerequest)))) { | |
53 | if (OpenDevice((STRPTR) TIMERNAME, UNIT_MICROHZ, (struct IORequest *) timerio, 0) == 0) { | |
54 | #if defined(__MORPHOS__) || defined(__VBCC__) | |
55 | TimerBase = (struct Library *)timerio->tr_node.io_Device; | |
56 | #else | |
57 | TimerBase = timerio->tr_node.io_Device; | |
58 | #endif | |
59 | } | |
60 | else { | |
61 | DeleteIORequest((struct IORequest *)timerio); | |
62 | DeleteMsgPort(timerport); | |
63 | } | |
64 | } | |
65 | else { | |
66 | DeleteMsgPort(timerport); | |
67 | } | |
68 | } | |
69 | if (!TimerBase) { | |
70 | fprintf(stderr, "Can't open timer.device\n"); | |
71 | exit (-1); | |
72 | } | |
73 | ||
74 | /* 1us wait, for timer cleanup success */ | |
75 | timerio->tr_node.io_Command = TR_ADDREQUEST; | |
76 | timerio->tr_time.tv_secs = 0; | |
77 | timerio->tr_time.tv_micro = 1; | |
78 | SendIO((struct IORequest *) timerio); | |
79 | WaitIO((struct IORequest *) timerio); | |
80 | ||
81 | amiga_stdout = Output(); | |
82 | amiga_stdin = Input(); | |
83 | SetMode(amiga_stdin, MODE_RAW); | |
84 | ||
85 | atexit (amiga_atexit); | |
86 | } | |
87 | ||
88 | int amiga_getch (unsigned char *c) { | |
89 | if (WaitForChar(amiga_stdin,10)) { | |
90 | return Read (amiga_stdin, c, 1); | |
91 | } | |
92 | return 0; | |
93 | } | |
94 | ||
95 | void amiga_usleep(unsigned long timeout) { | |
96 | timerio->tr_node.io_Command = TR_ADDREQUEST; | |
97 | timerio->tr_time.tv_secs = timeout / 1000000; | |
98 | timerio->tr_time.tv_micro = timeout % 1000000; | |
99 | SendIO((struct IORequest *) timerio); | |
100 | WaitIO((struct IORequest *) timerio); | |
101 | } |
77 | 77 | UNUSED(hmi_size); |
78 | 78 | |
79 | 79 | if (memcmp(hmi_data, "HMI-MIDISONG061595", 18)) { |
80 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_HMI, NULL, 0); | |
80 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, NULL, 0); | |
81 | 81 | return NULL; |
82 | 82 | } |
83 | 83 | |
113 | 113 | smallest_delta = 0xffffffff; |
114 | 114 | |
115 | 115 | if (hmi_size < (370 + (hmi_track_cnt * 17))) { |
116 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0); | |
116 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0); | |
117 | 117 | goto _hmi_end; |
118 | 118 | } |
119 | 119 | |
126 | 126 | hmi_track_offset[i] += (*hmi_data++ << 24); |
127 | 127 | |
128 | 128 | if (hmi_size < (hmi_track_offset[i] + 0x5a + 4)) { |
129 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0); | |
129 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0); | |
130 | 130 | goto _hmi_end; |
131 | 131 | } |
132 | 132 | |
133 | 133 | hmi_addr = hmi_base + hmi_track_offset[i]; |
134 | 134 | |
135 | 135 | if (memcmp(hmi_addr, "HMI-MIDITRACK", 13)) { |
136 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_HMI, NULL, 0); | |
136 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, NULL, 0); | |
137 | 137 | goto _hmi_end; |
138 | 138 | } |
139 | 139 | |
230 | 230 | hmi_track_offset[i] += 4; |
231 | 231 | } else { |
232 | 232 | if ((setup_ret = _WM_SetupMidiEvent(hmi_mdi,hmi_data,hmi_running_event[i])) == 0) { |
233 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); | |
234 | 233 | goto _hmi_end; |
235 | 234 | } |
236 | 235 | if ((hmi_data[0] == 0xff) && (hmi_data[1] == 0x2f) && (hmi_data[2] == 0x00)) { |
330 | 329 | } |
331 | 330 | |
332 | 331 | if ((hmi_mdi->reverb = _WM_init_reverb(_WM_SampleRate, _WM_reverb_room_width, _WM_reverb_room_length, _WM_reverb_listen_posx, _WM_reverb_listen_posy)) == NULL) { |
333 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
332 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
334 | 333 | goto _hmi_end; |
335 | 334 | } |
336 | 335 | |
353 | 352 | _WM_freeMDI(hmi_mdi); |
354 | 353 | return 0; |
355 | 354 | } |
356 |
74 | 74 | float sample_remainder = 0; |
75 | 75 | |
76 | 76 | if (memcmp(hmp_data, "HMIMIDIP", 8)) { |
77 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_HMP, NULL, 0); | |
77 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMP, NULL, 0); | |
78 | 78 | return NULL; |
79 | 79 | } |
80 | 80 | hmp_data += 8; |
94 | 94 | } |
95 | 95 | for (i = 0; i < zero_cnt; i++) { |
96 | 96 | if (hmp_data[i] != 0) { |
97 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_HMP, NULL, 0); | |
97 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMP, NULL, 0); | |
98 | 98 | return NULL; |
99 | 99 | } |
100 | 100 | } |
202 | 202 | chunk_ofs[i] += 4; |
203 | 203 | |
204 | 204 | if (chunk_length[i] > hmp_size) { |
205 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_HMP, "file too short", 0); | |
205 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMP, "file too short", 0); | |
206 | 206 | goto _hmp_end; |
207 | 207 | } |
208 | 208 | hmp_size -= chunk_length[i]; |
276 | 276 | uint32_t setup_ret = 0; |
277 | 277 | |
278 | 278 | if ((setup_ret = _WM_SetupMidiEvent(hmp_mdi, hmp_chunk[i], 0)) == 0) { |
279 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); | |
280 | 279 | goto _hmp_end; |
281 | 280 | } |
282 | 281 | |
330 | 329 | } |
331 | 330 | |
332 | 331 | if ((hmp_mdi->reverb = _WM_init_reverb(_WM_SampleRate, _WM_reverb_room_width, _WM_reverb_room_length, _WM_reverb_listen_posx, _WM_reverb_listen_posy)) == NULL) { |
333 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
332 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
334 | 333 | goto _hmp_end; |
335 | 334 | } |
336 | 335 |
68 | 68 | uint32_t setup_ret = 0; |
69 | 69 | |
70 | 70 | if (midi_size < 14) { |
71 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
71 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
72 | 72 | return (NULL); |
73 | 73 | } |
74 | 74 | |
75 | 75 | if (!memcmp(midi_data, "RIFF", 4)) { |
76 | 76 | if (midi_size < 34) { |
77 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
77 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
78 | 78 | return (NULL); |
79 | 79 | } |
80 | 80 | midi_data += 20; |
82 | 82 | } |
83 | 83 | |
84 | 84 | if (memcmp(midi_data, "MThd", 4)) { |
85 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_MIDI, NULL, 0); | |
85 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_MIDI, NULL, 0); | |
86 | 86 | return (NULL); |
87 | 87 | } |
88 | 88 | midi_data += 4; |
97 | 97 | tmp_val |= *midi_data++; |
98 | 98 | midi_size -= 4; |
99 | 99 | if (tmp_val != 6) { |
100 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, NULL, 0); | |
100 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); | |
101 | 101 | return (NULL); |
102 | 102 | } |
103 | 103 | |
108 | 108 | tmp_val |= *midi_data++; |
109 | 109 | midi_size -= 2; |
110 | 110 | if (tmp_val > 2) { |
111 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID, NULL, 0); | |
111 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, NULL, 0); | |
112 | 112 | return (NULL); |
113 | 113 | } |
114 | 114 | midi_type = tmp_val; |
120 | 120 | tmp_val |= *midi_data++; |
121 | 121 | midi_size -= 2; |
122 | 122 | if (tmp_val < 1) { |
123 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(no tracks)", 0); | |
123 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(no tracks)", 0); | |
124 | 124 | return (NULL); |
125 | 125 | } |
126 | 126 | no_tracks = tmp_val; |
129 | 129 | * Check that type 0 midi file has only 1 track |
130 | 130 | */ |
131 | 131 | if ((midi_type == 0) && (no_tracks > 1)) { |
132 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID, "(expected 1 track for type 0 midi file, found more)", 0); | |
132 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, "(expected 1 track for type 0 midi file, found more)", 0); | |
133 | 133 | return (NULL); |
134 | 134 | } |
135 | 135 | |
140 | 140 | divisions |= *midi_data++; |
141 | 141 | midi_size -= 2; |
142 | 142 | if (divisions & 0x00008000) { |
143 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID, NULL, 0); | |
143 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, NULL, 0); | |
144 | 144 | return (NULL); |
145 | 145 | } |
146 | 146 | |
157 | 157 | smallest_delta = 0xffffffff; |
158 | 158 | for (i = 0; i < no_tracks; i++) { |
159 | 159 | if (midi_size < 8) { |
160 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
160 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
161 | 161 | goto _end; |
162 | 162 | } |
163 | 163 | if (memcmp(midi_data, "MTrk", 4) != 0) { |
164 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(missing track header)", 0); | |
164 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(missing track header)", 0); | |
165 | 165 | goto _end; |
166 | 166 | } |
167 | 167 | midi_data += 4; |
173 | 173 | track_size |= *midi_data++; |
174 | 174 | midi_size -= 4; |
175 | 175 | if (midi_size < track_size) { |
176 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
176 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
177 | 177 | goto _end; |
178 | 178 | } |
179 | 179 | if (track_size < 3) { |
180 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(bad track size)", 0); | |
180 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(bad track size)", 0); | |
181 | 181 | goto _end; |
182 | 182 | } |
183 | 183 | if ((midi_data[track_size - 3] != 0xFF) |
184 | 184 | || (midi_data[track_size - 2] != 0x2F) |
185 | 185 | || (midi_data[track_size - 1] != 0x00)) { |
186 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(missing EOT)", 0); | |
186 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(missing EOT)", 0); | |
187 | 187 | goto _end; |
188 | 188 | } |
189 | 189 | tracks[i] = midi_data; |
244 | 244 | do { |
245 | 245 | setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], running_event[i]); |
246 | 246 | if (setup_ret == 0) { |
247 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); | |
248 | 247 | goto _end; |
249 | 248 | } |
250 | 249 | if (tracks[i][0] > 0x7f) { |
306 | 305 | do { |
307 | 306 | setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], running_event[i]); |
308 | 307 | if (setup_ret == 0) { |
309 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); | |
310 | 308 | goto _end; |
311 | 309 | } |
312 | 310 | if (tracks[i][0] > 0x7f) { |
357 | 355 | if ((mdi->reverb = _WM_init_reverb(_WM_SampleRate, _WM_reverb_room_width, |
358 | 356 | _WM_reverb_room_length, _WM_reverb_listen_posx, _WM_reverb_listen_posy)) |
359 | 357 | == NULL) { |
360 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
358 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
361 | 359 | goto _end; |
362 | 360 | } |
363 | 361 | |
410 | 408 | uint32_t track_count = 0; |
411 | 409 | |
412 | 410 | if (!mdi->event_count) { |
413 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CONVERT, "(No events to convert)", 0); | |
411 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CONVERT, "(No events to convert)", 0); | |
414 | 412 | return -1; |
415 | 413 | } |
416 | 414 | |
678 | 676 | } else if (event->do_event == _WM_do_sysex_roland_drum_track) { |
679 | 677 | // DEBUG |
680 | 678 | // fprintf(stderr,"Sysex Roland Drum Track: %u %.4x\r\n",event->event_data.channel, event->event_data.data); |
681 | int8_t foo[] = {0xf0, 0x09, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x15, 0x00, 0xf7}; | |
679 | uint8_t foo[] = {0xf0, 0x09, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x15, 0x00, 0xf7}; | |
682 | 680 | uint8_t foo_ch = event->event_data.channel; |
683 | 681 | if (foo_ch == 9) { |
684 | 682 | foo_ch = 0; |
693 | 691 | } else if (event->do_event == _WM_do_sysex_gm_reset) { |
694 | 692 | // DEBUG |
695 | 693 | // fprintf(stderr,"Sysex GM Reset\r\n"); |
696 | int8_t foo[] = {0xf0, 0x05, 0x7e, 0x7f, 0x09, 0x01, 0xf7}; | |
694 | uint8_t foo[] = {0xf0, 0x05, 0x7e, 0x7f, 0x09, 0x01, 0xf7}; | |
697 | 695 | memcpy(&((*out)[out_ofs]),foo,7); |
698 | 696 | out_ofs += 7; |
699 | 697 | running_event = 0; |
700 | 698 | } else if (event->do_event == _WM_do_sysex_roland_reset) { |
701 | 699 | // DEBUG |
702 | 700 | // fprintf(stderr,"Sysex Roland Reset\r\n"); |
703 | int8_t foo[] = {0xf0, 0x0a, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7}; | |
701 | uint8_t foo[] = {0xf0, 0x0a, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7}; | |
704 | 702 | memcpy(&((*out)[out_ofs]),foo,12); |
705 | 703 | out_ofs += 12; |
706 | 704 | running_event = 0; |
707 | 705 | } else if (event->do_event == _WM_do_sysex_yamaha_reset) { |
708 | 706 | // DEBUG |
709 | 707 | // fprintf(stderr,"Sysex Yamaha Reset\r\n"); |
710 | int8_t foo[] = {0xf0, 0x08, 0x43, 0x10, 0x4c, 0x00, 0x00, 0x7e, 0x00, 0xf7}; | |
708 | uint8_t foo[] = {0xf0, 0x08, 0x43, 0x10, 0x4c, 0x00, 0x00, 0x7e, 0x00, 0xf7}; | |
711 | 709 | memcpy(&((*out)[out_ofs]),foo,10); |
712 | 710 | out_ofs += 10; |
713 | 711 | running_event = 0; |
71 | 71 | uint16_t pitchbend_tmp = 0; |
72 | 72 | |
73 | 73 | if (mus_size < 17) { |
74 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_MUS, "File too short", 0); | |
74 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_MUS, "File too short", 0); | |
75 | 75 | return NULL; |
76 | 76 | } |
77 | 77 | |
78 | 78 | if (memcmp(mus_data, mus_hdr, 4)) { |
79 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_MUS, NULL, 0); | |
79 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_MUS, NULL, 0); | |
80 | 80 | return NULL; |
81 | 81 | } |
82 | 82 | |
100 | 100 | |
101 | 101 | // Check that we have enough data to check the rest |
102 | 102 | if (mus_size < (mus_data_ofs + (mus_no_instr << 1) + mus_song_len)) { |
103 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_MUS, "File too short", 0); | |
103 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_MUS, "File too short", 0); | |
104 | 104 | return NULL; |
105 | 105 | } |
106 | 106 | |
315 | 315 | |
316 | 316 | setup_ret = _WM_SetupMidiEvent(mus_mdi, (uint8_t *)mus_event, 0); |
317 | 317 | if (setup_ret == 0) { |
318 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); | |
319 | 318 | goto _mus_end; |
320 | 319 | } |
321 | 320 | |
344 | 343 | _mus_end_of_song: |
345 | 344 | // Finalise mdi structure |
346 | 345 | if ((mus_mdi->reverb = _WM_init_reverb(_WM_SampleRate, _WM_reverb_room_width, _WM_reverb_room_length, _WM_reverb_listen_posx, _WM_reverb_listen_posy)) == NULL) { |
347 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
346 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
348 | 347 | goto _mus_end; |
349 | 348 | } |
350 | 349 | _WM_midi_setup_endoftrack(mus_mdi); |
63 | 63 | |
64 | 64 | |
65 | 65 | if (memcmp(xmi_data,"FORM",4)) { |
66 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
66 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
67 | 67 | return NULL; |
68 | 68 | } |
69 | 69 | |
78 | 78 | xmi_size -= 4; |
79 | 79 | |
80 | 80 | if (memcmp(xmi_data,"XDIRINFO",8)) { |
81 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
81 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
82 | 82 | return NULL; |
83 | 83 | } |
84 | 84 | xmi_data += 8; |
94 | 94 | // number of forms contained after this point |
95 | 95 | xmi_formcnt = *xmi_data++; |
96 | 96 | if (xmi_formcnt == 0) { |
97 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
97 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
98 | 98 | return NULL; |
99 | 99 | } |
100 | 100 | xmi_size--; |
109 | 109 | |
110 | 110 | /* FIXME: Check: may not even need to process CAT information */ |
111 | 111 | if (memcmp(xmi_data,"CAT ",4)) { |
112 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
112 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
113 | 113 | return NULL; |
114 | 114 | } |
115 | 115 | xmi_data += 4; |
124 | 124 | UNUSED(xmi_catlen); |
125 | 125 | |
126 | 126 | if (memcmp(xmi_data,"XMID",4)) { |
127 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
127 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
128 | 128 | return NULL; |
129 | 129 | } |
130 | 130 | xmi_data += 4; |
141 | 141 | |
142 | 142 | for (i = 0; i < xmi_formcnt; i++) { |
143 | 143 | if (memcmp(xmi_data,"FORM",4)) { |
144 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
144 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
145 | 145 | goto _xmi_end; |
146 | 146 | } |
147 | 147 | xmi_data += 4; |
154 | 154 | xmi_size -= 4; |
155 | 155 | |
156 | 156 | if (memcmp(xmi_data,"XMID",4)) { |
157 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
157 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
158 | 158 | goto _xmi_end; |
159 | 159 | } |
160 | 160 | xmi_data += 4; |
267 | 267 | goto _XMI_Next_Event; |
268 | 268 | } |
269 | 269 | if ((setup_ret = _WM_SetupMidiEvent(xmi_mdi,xmi_data,0)) == 0) { |
270 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); | |
271 | 270 | goto _xmi_end; |
272 | 271 | } |
273 | 272 | |
313 | 312 | } while (xmi_evntlen); |
314 | 313 | |
315 | 314 | } else { |
316 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
315 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
317 | 316 | goto _xmi_end; |
318 | 317 | } |
319 | 318 | |
322 | 321 | |
323 | 322 | // Finalise mdi structure |
324 | 323 | if ((xmi_mdi->reverb = _WM_init_reverb(_WM_SampleRate, _WM_reverb_room_width, _WM_reverb_room_length, _WM_reverb_listen_posx, _WM_reverb_listen_posy)) == NULL) { |
325 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
324 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to init reverb", 0); | |
326 | 325 | goto _xmi_end; |
327 | 326 | } |
328 | 327 | xmi_mdi->extra_info.current_sample = 0; |
24 | 24 | |
25 | 25 | #include <stdint.h> |
26 | 26 | #include <errno.h> |
27 | #include <fcntl.h> | |
28 | 27 | #include <stdlib.h> |
29 | 28 | #include <string.h> |
29 | ||
30 | #ifndef WILDMIDI_AMIGA | |
31 | #include <fcntl.h> | |
30 | 32 | #include <sys/types.h> |
31 | 33 | #include <sys/stat.h> |
32 | ||
34 | #endif | |
33 | 35 | #ifdef _WIN32 |
36 | #include <windows.h> | |
34 | 37 | #include <io.h> |
35 | 38 | #undef close |
36 | 39 | #define close _close |
42 | 45 | #include <io.h> |
43 | 46 | #include <dir.h> |
44 | 47 | #include <unistd.h> |
48 | #elif defined(__OS2__) || defined(__EMX__) | |
49 | #define INCL_DOS | |
50 | #define INCL_DOSERRORS | |
51 | #include <os2.h> | |
52 | #include <fcntl.h> | |
53 | #include <io.h> | |
54 | #elif defined(WILDMIDI_AMIGA) | |
55 | #include <proto/exec.h> | |
56 | #include <proto/dos.h> | |
45 | 57 | #else |
46 | 58 | #include <pwd.h> |
47 | 59 | #include <strings.h> |
59 | 71 | #include "wm_error.h" |
60 | 72 | #include "file_io.h" |
61 | 73 | |
74 | #ifdef WILDMIDI_AMIGA | |
75 | static long AMIGA_filesize (const char *path) { | |
76 | long size = -1; | |
77 | BPTR fh = Open((const STRPTR) path, MODE_OLDFILE); | |
78 | if (fh) { | |
79 | struct FileInfoBlock *fib = (struct FileInfoBlock*) | |
80 | AllocDosObject(DOS_FIB, NULL); | |
81 | if (fib != NULL) { | |
82 | if (ExamineFH(fh, fib)) | |
83 | size = fib->fib_Size; | |
84 | FreeDosObject(DOS_FIB, fib); | |
85 | } | |
86 | Close(fh); | |
87 | } | |
88 | return size; | |
89 | } | |
90 | ||
91 | static long AMIGA_read (BPTR fd, unsigned char *buf, long size) { | |
92 | long bytes_read = 0, result; | |
93 | while (bytes_read < size) { | |
94 | result = Read(fd, buf + bytes_read, size - bytes_read); | |
95 | if (result < 0) return result; | |
96 | if (result == 0) break; | |
97 | bytes_read += result; | |
98 | } | |
99 | return bytes_read; | |
100 | } | |
101 | ||
102 | static BPTR AMIGA_open (const char *path) { | |
103 | return Open((const STRPTR) path, MODE_OLDFILE); | |
104 | } | |
105 | ||
106 | static void AMIGA_close (BPTR fd) { | |
107 | Close(fd); | |
108 | } | |
109 | #endif | |
110 | ||
62 | 111 | void *_WM_BufferFile(const char *filename, uint32_t *size) { |
63 | int buffer_fd; | |
112 | char *buffer_file = NULL; | |
64 | 113 | uint8_t *data; |
65 | 114 | #ifdef __DJGPP__ |
115 | int buffer_fd; | |
66 | 116 | struct ffblk f; |
67 | #else | |
117 | #elif defined(_WIN32) | |
118 | int buffer_fd; | |
119 | HANDLE h; | |
120 | WIN32_FIND_DATA wfd; | |
121 | #elif defined(__OS2__) || defined(__EMX__) | |
122 | int buffer_fd; | |
123 | HDIR h = HDIR_CREATE; | |
124 | FILEFINDBUF3 fb = {0}; | |
125 | ULONG cnt = 1; | |
126 | #elif defined(WILDMIDI_AMIGA) | |
127 | BPTR buffer_fd; | |
128 | long filsize; | |
129 | #elif defined(_3DS) || defined(GEKKO) | |
130 | int buffer_fd; | |
68 | 131 | struct stat buffer_stat; |
69 | #endif | |
70 | #if !defined(_WIN32) && !defined(__DJGPP__) | |
132 | #else /* unix builds */ | |
133 | int buffer_fd; | |
134 | struct stat buffer_stat; | |
135 | ||
136 | /* for basedir of filename: */ | |
71 | 137 | const char *home = NULL; |
72 | 138 | struct passwd *pwd_ent; |
73 | 139 | char buffer_dir[1024]; |
74 | #endif /* unix builds */ | |
75 | char *buffer_file = NULL; | |
76 | ||
77 | #if !defined(_WIN32) && !defined(__DJGPP__) | |
140 | ||
78 | 141 | if (strncmp(filename, "~/", 2) == 0) { |
79 | 142 | if ((pwd_ent = getpwuid(getuid()))) { |
80 | 143 | home = pwd_ent->pw_dir; |
84 | 147 | if (home) { |
85 | 148 | buffer_file = malloc(strlen(filename) + strlen(home) + 1); |
86 | 149 | if (buffer_file == NULL) { |
87 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, errno); | |
88 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, filename, errno); | |
150 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, filename, errno); | |
89 | 151 | return NULL; |
90 | 152 | } |
91 | 153 | strcpy(buffer_file, home); |
96 | 158 | if (cwdresult != NULL) |
97 | 159 | buffer_file = malloc(strlen(filename) + strlen(buffer_dir) + 2); |
98 | 160 | if (buffer_file == NULL || cwdresult == NULL) { |
99 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, errno); | |
100 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, filename, errno); | |
161 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, filename, errno); | |
101 | 162 | return NULL; |
102 | 163 | } |
103 | 164 | strcpy(buffer_file, buffer_dir); |
105 | 166 | strcat(buffer_file, "/"); |
106 | 167 | strcat(buffer_file, filename); |
107 | 168 | } |
108 | #endif | |
169 | #endif /* unix builds */ | |
109 | 170 | |
110 | 171 | if (buffer_file == NULL) { |
111 | 172 | buffer_file = malloc(strlen(filename) + 1); |
112 | 173 | if (buffer_file == NULL) { |
113 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, errno); | |
114 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, filename, errno); | |
174 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, filename, errno); | |
115 | 175 | return NULL; |
116 | 176 | } |
117 | 177 | strcpy(buffer_file, filename); |
119 | 179 | |
120 | 180 | #ifdef __DJGPP__ |
121 | 181 | if (findfirst(buffer_file, &f, FA_ARCH | FA_RDONLY) != 0) { |
122 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_STAT, filename, errno); | |
182 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_STAT, filename, errno); | |
123 | 183 | free(buffer_file); |
124 | 184 | return NULL; |
125 | 185 | } |
126 | 186 | *size = f.ff_fsize; |
187 | #elif defined(_WIN32) | |
188 | if ((h = FindFirstFile(buffer_file, &wfd)) == INVALID_HANDLE_VALUE) { | |
189 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_STAT, filename, ENOENT); | |
190 | free(buffer_file); | |
191 | return NULL; | |
192 | } | |
193 | FindClose(h); | |
194 | if (wfd.nFileSizeHigh != 0) /* too big */ | |
195 | *size = 0xffffffff; | |
196 | else *size = wfd.nFileSizeLow; | |
197 | #elif defined(__OS2__) || defined(__EMX__) | |
198 | if (DosFindFirst(buffer_file, &h, FILE_NORMAL, &fb, sizeof(fb), &cnt, FIL_STANDARD) != NO_ERROR) { | |
199 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_STAT, filename, ENOENT); | |
200 | free(buffer_file); | |
201 | return NULL; | |
202 | } | |
203 | DosFindClose(h); | |
204 | *size = fb.cbFile; | |
205 | #elif defined(WILDMIDI_AMIGA) | |
206 | if ((filsize = AMIGA_filesize(buffer_file)) < 0) { | |
207 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_STAT, filename, ENOENT /* do better!! */); | |
208 | free(buffer_file); | |
209 | return NULL; | |
210 | } | |
211 | *size = filsize; | |
127 | 212 | #else |
128 | 213 | if (stat(buffer_file, &buffer_stat)) { |
129 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_STAT, filename, errno); | |
130 | free(buffer_file); | |
131 | return NULL; | |
132 | } | |
133 | *size = buffer_stat.st_size; | |
214 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_STAT, filename, errno); | |
215 | free(buffer_file); | |
216 | return NULL; | |
217 | } | |
218 | /* st_size can be sint32 or int64. */ | |
219 | if (buffer_stat.st_size > WM_MAXFILESIZE) /* too big */ | |
220 | *size = 0xffffffff; | |
221 | else *size = buffer_stat.st_size; | |
134 | 222 | #endif |
135 | 223 | |
136 | 224 | if (__builtin_expect((*size > WM_MAXFILESIZE), 0)) { |
137 | 225 | /* don't bother loading suspiciously long files */ |
138 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LONGFIL, filename, 0); | |
226 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_LONGFIL, filename, 0); | |
139 | 227 | free(buffer_file); |
140 | 228 | return NULL; |
141 | 229 | } |
143 | 231 | /* +1 needed for parsing text files without a newline at the end */ |
144 | 232 | data = (uint8_t *) malloc(*size + 1); |
145 | 233 | if (data == NULL) { |
146 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, errno); | |
147 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, filename, errno); | |
148 | free(buffer_file); | |
149 | return NULL; | |
150 | } | |
151 | ||
234 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, filename, errno); | |
235 | free(buffer_file); | |
236 | return NULL; | |
237 | } | |
238 | ||
239 | #if defined(WILDMIDI_AMIGA) | |
240 | if (!(buffer_fd = AMIGA_open(buffer_file))) { | |
241 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_OPEN, filename, ENOENT /* do better!! */); | |
242 | free(buffer_file); | |
243 | free(data); | |
244 | return NULL; | |
245 | } | |
246 | if (AMIGA_read(buffer_fd, data, filsize) != filsize) { | |
247 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_READ, filename, EIO /* do better!! */); | |
248 | free(buffer_file); | |
249 | free(data); | |
250 | AMIGA_close(buffer_fd); | |
251 | return NULL; | |
252 | } | |
253 | AMIGA_close(buffer_fd); | |
254 | free(buffer_file); | |
255 | #else | |
152 | 256 | if ((buffer_fd = open(buffer_file,(O_RDONLY | O_BINARY))) == -1) { |
153 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_OPEN, filename, errno); | |
257 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_OPEN, filename, errno); | |
154 | 258 | free(buffer_file); |
155 | 259 | free(data); |
156 | 260 | return NULL; |
157 | 261 | } |
158 | 262 | if (read(buffer_fd, data, *size) != (long) *size) { |
159 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_READ, filename, errno); | |
263 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_READ, filename, errno); | |
160 | 264 | free(buffer_file); |
161 | 265 | free(data); |
162 | 266 | close(buffer_fd); |
163 | 267 | return NULL; |
164 | 268 | } |
165 | data[*size] = '\0'; | |
166 | ||
167 | 269 | close(buffer_fd); |
168 | 270 | free(buffer_file); |
271 | #endif | |
272 | ||
273 | data[*size] = '\0'; | |
169 | 274 | return data; |
170 | 275 | } |
52 | 52 | #define GUSPAT_END_DEBUG() |
53 | 53 | #endif |
54 | 54 | |
55 | /* | |
56 | * sample data conversion functions | |
55 | /* sample data conversion functions | |
57 | 56 | * convert data to signed shorts |
58 | 57 | */ |
59 | 58 | |
73 | 72 | return 0; |
74 | 73 | } |
75 | 74 | |
76 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, 0, "calloc failed", errno); | |
75 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, 0, "calloc failed", errno); | |
77 | 76 | |
78 | 77 | return -1; |
79 | 78 | } |
126 | 125 | return 0; |
127 | 126 | } |
128 | 127 | |
129 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
128 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
130 | 129 | return -1; |
131 | 130 | } |
132 | 131 | |
152 | 151 | gus_sample->modes ^= SAMPLE_REVERSE; |
153 | 152 | return 0; |
154 | 153 | } |
155 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
154 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
156 | 155 | return -1; |
157 | 156 | } |
158 | 157 | |
203 | 202 | return 0; |
204 | 203 | } |
205 | 204 | |
206 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
205 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
207 | 206 | return -1; |
208 | 207 | } |
209 | 208 | |
223 | 222 | gus_sample->modes ^= SAMPLE_UNSIGNED; |
224 | 223 | return 0; |
225 | 224 | } |
226 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
225 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
227 | 226 | return -1; |
228 | 227 | } |
229 | 228 | |
275 | 274 | return 0; |
276 | 275 | } |
277 | 276 | |
278 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
277 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
279 | 278 | return -1; |
280 | 279 | } |
281 | 280 | |
301 | 300 | gus_sample->modes ^= SAMPLE_REVERSE | SAMPLE_UNSIGNED; |
302 | 301 | return 0; |
303 | 302 | } |
304 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
303 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
305 | 304 | return -1; |
306 | 305 | } |
307 | 306 | |
351 | 350 | return 0; |
352 | 351 | } |
353 | 352 | |
354 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
353 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
355 | 354 | return -1; |
356 | 355 | } |
357 | 356 | |
375 | 374 | gus_sample->data_length >>= 1; |
376 | 375 | return 0; |
377 | 376 | } |
378 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
377 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
379 | 378 | return -1; |
380 | 379 | } |
381 | 380 | |
435 | 434 | return 0; |
436 | 435 | } |
437 | 436 | |
438 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
437 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
439 | 438 | return -1; |
440 | 439 | } |
441 | 440 | |
465 | 464 | gus_sample->modes ^= SAMPLE_REVERSE; |
466 | 465 | return 0; |
467 | 466 | } |
468 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
467 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
469 | 468 | return -1; |
470 | 469 | } |
471 | 470 | |
520 | 519 | return 0; |
521 | 520 | } |
522 | 521 | |
523 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
522 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
524 | 523 | return -1; |
525 | 524 | } |
526 | 525 | |
544 | 543 | gus_sample->modes ^= SAMPLE_UNSIGNED; |
545 | 544 | return 0; |
546 | 545 | } |
547 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
546 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
548 | 547 | return -1; |
549 | 548 | } |
550 | 549 | |
604 | 603 | return 0; |
605 | 604 | } |
606 | 605 | |
607 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
606 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
608 | 607 | return -1; |
609 | 608 | } |
610 | 609 | |
634 | 633 | gus_sample->modes ^= SAMPLE_REVERSE | SAMPLE_UNSIGNED; |
635 | 634 | return 0; |
636 | 635 | } |
637 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
636 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
638 | 637 | return -1; |
639 | 638 | } |
640 | 639 | |
689 | 688 | return 0; |
690 | 689 | } |
691 | 690 | |
692 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
691 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno); | |
693 | 692 | return -1; |
694 | 693 | } |
695 | 694 | |
732 | 731 | return NULL; |
733 | 732 | } |
734 | 733 | if (gus_size < 239) { |
735 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
736 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, filename, 0); | |
734 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, filename, 0); | |
737 | 735 | free(gus_patch); |
738 | 736 | return NULL; |
739 | 737 | } |
740 | 738 | if (memcmp(gus_patch, "GF1PATCH110\0ID#000002", 22) |
741 | 739 | && memcmp(gus_patch, "GF1PATCH100\0ID#000002", 22)) { |
742 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID, "(unsupported format)", | |
743 | 0); | |
744 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, filename, 0); | |
740 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, filename, 0); | |
745 | 741 | free(gus_patch); |
746 | 742 | return NULL; |
747 | 743 | } |
748 | 744 | if (gus_patch[82] > 1) { |
749 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID, "(unsupported format)", | |
750 | 0); | |
751 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, filename, 0); | |
745 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, filename, 0); | |
752 | 746 | free(gus_patch); |
753 | 747 | return NULL; |
754 | 748 | } |
755 | 749 | if (gus_patch[151] > 1) { |
756 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID, "(unsupported format)", | |
757 | 0); | |
758 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, filename, 0); | |
750 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, filename, 0); | |
759 | 751 | free(gus_patch); |
760 | 752 | return NULL; |
761 | 753 | } |
775 | 767 | gus_sample = gus_sample->next; |
776 | 768 | } |
777 | 769 | if (gus_sample == NULL) { |
778 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, 0); | |
779 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, filename, 0); | |
770 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, filename, 0); | |
780 | 771 | free(gus_patch); |
781 | 772 | return NULL; |
782 | 773 | } |
918 | 909 | / ((float) _WM_SampleRate * env_time_table[env_rate])); |
919 | 910 | GUSPAT_INT_DEBUG("Envelope Rate",gus_sample->env_rate[i]); GUSPAT_INT_DEBUG("GUSPAT Rate",env_rate); |
920 | 911 | if (gus_sample->env_rate[i] == 0) { |
921 | _WM_ERROR_NEW("%s: Warning: found invalid envelope(%u) rate setting in %s. Using %f instead.", | |
912 | _WM_DEBUG_MSG("%s: Warning: found invalid envelope(%u) rate setting in %s. Using %f instead.", | |
922 | 913 | __FUNCTION__, i, filename, env_time_table[63]); |
923 | 914 | gus_sample->env_rate[i] = (int32_t) (4194303.0 |
924 | 915 | / ((float) _WM_SampleRate * env_time_table[63])); |
38 | 38 | #include "internal_midi.h" |
39 | 39 | #ifdef __DJGPP__ |
40 | 40 | #define powf pow /* prefer C89 pow() from libc.a instead of powf() from libm. */ |
41 | #endif | |
42 | #ifdef WILDMIDI_AMIGA | |
43 | #define powf pow | |
44 | #endif | |
45 | #if defined(__WATCOMC__) || defined(__EMX__) | |
46 | #define powf pow | |
41 | 47 | #endif |
42 | 48 | |
43 | 49 | #define HOLD_OFF 0x02 |
92 | 98 | -0.5559443807, -0.4152814317, -0.2757483179, -0.1373270335, 0.0 }; |
93 | 99 | |
94 | 100 | /* f: As per midi 2 standard */ |
95 | static float dBm_pan_volume[] = { -999999.999999, -38.15389834 -32.13396282, | |
101 | static float dBm_pan_volume[] = { -999999.999999, -38.15389834, -32.13396282, | |
96 | 102 | -28.61324502, -26.1160207, -24.179814, -22.5986259, -21.26257033, |
97 | 103 | -20.10605521, -19.08677237, -18.17583419, -17.35263639, -16.60196565, |
98 | 104 | -15.91226889, -15.2745658, -14.6817375, -14.12804519, -13.60879499, |
2344 | 2350 | } |
2345 | 2351 | } else { |
2346 | 2352 | /* For non-Roland Sysex Messages */ |
2347 | int8_t gm_reset[] = {0x7e, 0x7f, 0x09, 0x01, 0xf7}; | |
2348 | int8_t yamaha_reset[] = {0x43, 0x10, 0x4c, 0x00, 0x00, 0x7e, 0x00, 0xf7}; | |
2353 | uint8_t gm_reset[] = {0x7e, 0x7f, 0x09, 0x01, 0xf7}; | |
2354 | uint8_t yamaha_reset[] = {0x43, 0x10, 0x4c, 0x00, 0x00, 0x7e, 0x00, 0xf7}; | |
2349 | 2355 | |
2350 | 2356 | if (memcmp(gm_reset, sysex_store, 5) == 0) { |
2351 | 2357 | /* GM Reset */ |
2364 | 2370 | */ |
2365 | 2371 | ret_cnt += sysex_len; |
2366 | 2372 | } else { |
2367 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(unrecognized meta type event)", 0); | |
2373 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(unrecognized meta type event)", 0); | |
2368 | 2374 | return 0; |
2369 | 2375 | } |
2370 | 2376 | break; |
2371 | 2377 | |
2372 | 2378 | default: /* Should NEVER get here */ |
2373 | return 0; | |
2374 | } | |
2379 | ret_cnt = 0; | |
2380 | break; | |
2381 | } | |
2382 | if (ret_cnt == 0) | |
2383 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); | |
2375 | 2384 | return ret_cnt; |
2376 | 2385 | } |
2377 | 2386 |
23 | 23 | |
24 | 24 | #include "config.h" |
25 | 25 | |
26 | #ifndef __DJGPP__ | |
26 | #if !defined(WM_NO_LOCK) | |
27 | 27 | |
28 | #include <stdint.h> | |
29 | 28 | #ifdef _WIN32 |
30 | 29 | #include <windows.h> |
31 | #else | |
30 | #elif defined(__OS2__) || defined(__EMX__) | |
31 | #define INCL_DOS | |
32 | #include <os2.h> | |
33 | #elif defined(WILDMIDI_AMIGA) | |
34 | #include <proto/dos.h> | |
35 | #else /* unixish ... */ | |
32 | 36 | #define _GNU_SOURCE |
33 | #include <unistd.h> | |
37 | #include <unistd.h> /* usleep() */ | |
34 | 38 | #endif |
35 | 39 | |
36 | 40 | #include "lock.h" |
37 | #include "common.h" | |
38 | 41 | |
39 | 42 | /* |
40 | 43 | _WM_Lock(wmlock) |
62 | 65 | } |
63 | 66 | #ifdef _WIN32 |
64 | 67 | Sleep(10); |
68 | #elif defined(__OS2__) || defined(__EMX__) | |
69 | DosSleep(10); | |
70 | #elif defined(WILDMIDI_AMIGA) | |
71 | Delay(1); | |
65 | 72 | #else |
66 | 73 | usleep(500); |
67 | 74 | #endif |
84 | 91 | } |
85 | 92 | } |
86 | 93 | |
87 | #endif /* __DJGPP__ */ | |
94 | #endif /* !WM_NO_LOCK */ |
75 | 75 | |
76 | 76 | #define MIDI_MAXCHANNELS 16 |
77 | 77 | |
78 | static char MUS_ID[] = { 'M', 'U', 'S', 0x1A }; | |
79 | ||
80 | static uint8_t midimap[] = | |
78 | static const char MUS_ID[] = { 'M', 'U', 'S', 0x1A }; | |
79 | ||
80 | static const uint8_t midimap[] = | |
81 | 81 | {/* MIDI Number Description */ |
82 | 82 | 0, /* 0 program change */ |
83 | 83 | 0, /* 1 bank selection */ |
122 | 122 | #define TRK_CHUNKSIZE 8 |
123 | 123 | |
124 | 124 | struct mus_ctx { |
125 | uint8_t *src, *src_ptr; | |
125 | const uint8_t *src, *src_ptr; | |
126 | 126 | uint32_t srcsize; |
127 | 127 | uint32_t datastart; |
128 | 128 | uint8_t *dst, *dst_ptr; |
213 | 213 | #define READ_INT16(b) ((b)[0] | ((b)[1] << 8)) |
214 | 214 | #define READ_INT32(b) ((b)[0] | ((b)[1] << 8) | ((b)[2] << 16) | ((b)[3] << 24)) |
215 | 215 | |
216 | int _WM_mus2midi(uint8_t *in, uint32_t insize, | |
216 | int _WM_mus2midi(const uint8_t *in, uint32_t insize, | |
217 | 217 | uint8_t **out, uint32_t *outsize, |
218 | 218 | uint16_t frequency) { |
219 | 219 | struct mus_ctx ctx; |
220 | 220 | MUSHeader header; |
221 | uint8_t *cur, *end; | |
221 | const uint8_t *cur, *end; | |
222 | 222 | uint32_t track_size_pos, begin_track_pos, current_pos; |
223 | 223 | int32_t delta_time;/* Delta time for midi event */ |
224 | 224 | int temp, ret = -1; |
226 | 226 | int channelMap[MIDI_MAXCHANNELS], currentChannel; |
227 | 227 | |
228 | 228 | if (insize < MUS_HEADERSIZE) { |
229 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
229 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
230 | 230 | return (-1); |
231 | 231 | } |
232 | 232 | |
242 | 242 | header.instrCnt = READ_INT16(&in[12]); |
243 | 243 | |
244 | 244 | if (memcmp(header.ID, MUS_ID, 4)) { |
245 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_MUS, NULL, 0); | |
245 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_MUS, NULL, 0); | |
246 | 246 | return (-1); |
247 | 247 | } |
248 | 248 | if (insize < (uint32_t)header.scoreLen + (uint32_t)header.scoreStart) { |
249 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
249 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
250 | 250 | return (-1); |
251 | 251 | } |
252 | 252 | /* channel #15 should be excluded in the numchannels field: */ |
253 | 253 | if (header.channels > MIDI_MAXCHANNELS - 1) { |
254 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID, NULL, 0); | |
254 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, NULL, 0); | |
255 | 255 | return (-1); |
256 | 256 | } |
257 | 257 | |
391 | 391 | bit1 = 0x2f; |
392 | 392 | bit2 = 0x00; |
393 | 393 | if (cur != end) { /* should we error here or report-only? */ |
394 | _WM_ERROR_NEW("%s:%i: MUS buffer off by %ld bytes", | |
394 | _WM_DEBUG_MSG("%s:%i: MUS buffer off by %ld bytes", | |
395 | 395 | __FUNCTION__, __LINE__, (long)(cur - end)); |
396 | 396 | } |
397 | 397 | break; |
22 | 22 | |
23 | 23 | #include "config.h" |
24 | 24 | |
25 | #include <sys/types.h> | |
26 | 25 | #include <stdint.h> |
27 | 26 | #include <errno.h> |
28 | #include <fcntl.h> | |
29 | 27 | #include <stdio.h> |
30 | 28 | #include <stdlib.h> |
31 | 29 | #include <string.h> |
30 | ||
31 | #if defined(__DJGPP__) | |
32 | #include <sys/types.h> | |
33 | #include <fcntl.h> | |
32 | 34 | #include <sys/stat.h> |
33 | ||
34 | #if defined(__DJGPP__) | |
35 | 35 | #include "getopt_long.h" |
36 | 36 | #include <conio.h> |
37 | 37 | #define getopt dj_getopt /* hack */ |
43 | 43 | #ifdef AUDIODRV_DOSSB |
44 | 44 | #include "dossb.h" |
45 | 45 | #endif |
46 | #endif | |
47 | ||
48 | #if (defined _WIN32) || (defined __CYGWIN__) | |
46 | ||
47 | #elif (defined _WIN32) || (defined __CYGWIN__) | |
48 | #include <sys/types.h> | |
49 | #include <fcntl.h> | |
50 | #include <sys/stat.h> | |
49 | 51 | #include <conio.h> |
50 | 52 | #include <windows.h> |
51 | 53 | #include <mmsystem.h> |
52 | 54 | #define msleep(s) Sleep((s)) |
53 | 55 | #include <io.h> |
54 | #undef close | |
55 | #define close _close | |
56 | #undef open | |
57 | #define open _open | |
58 | #undef read | |
59 | #define read _read | |
60 | #undef write | |
61 | #define write _write | |
62 | #undef lseek | |
63 | #define lseek _lseek | |
64 | 56 | #include "getopt_long.h" |
57 | #ifdef __WATCOMC__ | |
58 | #define _putch putch | |
65 | 59 | #endif |
66 | 60 | |
67 | #if !defined(_WIN32) && !defined(__DJGPP__) /* unix build */ | |
61 | #elif defined(__OS2__) || defined(__EMX__) | |
62 | #define INCL_DOS | |
63 | #define INCL_DOSERRORS | |
64 | #define INCL_OS2MM | |
65 | #ifdef __EMX__ | |
66 | #define INCL_KBD | |
67 | #define INCL_VIO | |
68 | #endif | |
69 | #include <os2.h> | |
70 | #include <os2me.h> | |
71 | #include <conio.h> | |
72 | #define msleep(s) DosSleep((s)) | |
73 | #include <fcntl.h> | |
74 | #include <io.h> | |
75 | #include "getopt_long.h" | |
76 | #ifdef __EMX__ | |
77 | #include <sys/types.h> /* for off_t typedef */ | |
78 | int putch (int c) { | |
79 | char ch = c; | |
80 | VioWrtTTY(&ch, 1, 0); | |
81 | return c; | |
82 | } | |
83 | int kbhit (void) { | |
84 | KBDKEYINFO k; | |
85 | if (KbdPeek(&k, 0)) | |
86 | return 0; | |
87 | return (k.fbStatus & KBDTRF_FINAL_CHAR_IN); | |
88 | } | |
89 | #endif | |
90 | ||
91 | #elif defined(WILDMIDI_AMIGA) | |
92 | extern void amiga_sysinit (void); | |
93 | extern int amiga_usleep(unsigned long millisec); | |
94 | #define msleep(s) amiga_usleep((s)*1000) | |
95 | extern int amiga_getch (unsigned char *ch); | |
96 | #include <proto/exec.h> | |
97 | #include <proto/dos.h> | |
98 | #include "getopt_long.h" | |
99 | #ifdef AUDIODRV_AHI | |
100 | #include <devices/ahi.h> | |
101 | #endif | |
102 | ||
103 | #else /* unix build */ | |
68 | 104 | static int msleep(unsigned long millisec); |
105 | #include <sys/types.h> | |
106 | #include <fcntl.h> | |
107 | #include <sys/stat.h> | |
69 | 108 | #include <sys/ioctl.h> |
70 | 109 | #include <unistd.h> |
71 | 110 | #include <getopt.h> |
208 | 247 | static void (*close_output)(void); |
209 | 248 | static void (*pause_output)(void); |
210 | 249 | static void (*resume_output)(void); |
250 | ||
251 | #define wmidi_geterrno() errno /* generic case */ | |
252 | #if defined(_WIN32) | |
211 | 253 | static int audio_fd = -1; |
254 | #define WM_IS_BADF(_fd) ((_fd)<0) | |
255 | #define WM_BADF -1 | |
256 | static inline int wmidi_fileexists (const char *path) { | |
257 | return (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES); | |
258 | } | |
259 | static inline int wmidi_open_write (const char *path) { | |
260 | return _open(path, (O_RDWR | O_CREAT | O_TRUNC | O_BINARY), 0664); | |
261 | } | |
262 | static inline void wmidi_close (int fd) { | |
263 | _close(fd); | |
264 | } | |
265 | static inline long wmidi_seekset (int fd, long ofs) { | |
266 | return _lseek(fd, ofs, SEEK_SET); | |
267 | } | |
268 | static inline int wmidi_write (int fd, const void *buf, size_t size) { | |
269 | return _write(fd, buf, size); | |
270 | } | |
271 | ||
272 | #elif defined(__DJGPP__) | |
273 | static int audio_fd = -1; | |
274 | #define WM_IS_BADF(_fd) ((_fd)<0) | |
275 | #define WM_BADF -1 | |
276 | static inline int wmidi_fileexists (const char *path) { | |
277 | struct ffblk f; | |
278 | return (findfirst(path, &f, FA_ARCH | FA_RDONLY) == 0); | |
279 | } | |
280 | static inline int wmidi_open_write (const char *path) { | |
281 | return open(path, (O_RDWR | O_CREAT | O_TRUNC | O_BINARY), 0664); | |
282 | } | |
283 | static inline void wmidi_close (int fd) { | |
284 | close(fd); | |
285 | } | |
286 | static inline off_t wmidi_seekset (int fd, off_t ofs) { | |
287 | return lseek(fd, ofs, SEEK_SET); | |
288 | } | |
289 | static inline int wmidi_write (int fd, const void *buf, size_t size) { | |
290 | return write(fd, buf, size); | |
291 | } | |
292 | ||
293 | #elif defined(__OS2__) || defined(__EMX__) | |
294 | static int audio_fd = -1; | |
295 | #define WM_IS_BADF(_fd) ((_fd)<0) | |
296 | #define WM_BADF -1 | |
297 | static inline int wmidi_fileexists (const char *path) { | |
298 | int f = open(path, (O_RDONLY | O_BINARY)); | |
299 | if (f != -1) { close(f); return 1; } else return 0; | |
300 | } | |
301 | static inline int wmidi_open_write (const char *path) { | |
302 | return open(path, (O_RDWR | O_CREAT | O_TRUNC | O_BINARY), 0664); | |
303 | } | |
304 | static inline void wmidi_close (int fd) { | |
305 | close(fd); | |
306 | } | |
307 | static inline off_t wmidi_seekset (int fd, off_t ofs) { | |
308 | return lseek(fd, ofs, SEEK_SET); | |
309 | } | |
310 | static inline int wmidi_write (int fd, const void *buf, size_t size) { | |
311 | return write(fd, buf, size); | |
312 | } | |
313 | ||
314 | #elif defined(WILDMIDI_AMIGA) | |
315 | static BPTR audio_fd = 0; | |
316 | #define WM_IS_BADF(_fd) ((_fd)==0) | |
317 | #define WM_BADF 0 | |
318 | #undef wmidi_geterrno | |
319 | static int wmidi_geterrno (void) { | |
320 | switch (IoErr()) { | |
321 | case ERROR_OBJECT_NOT_FOUND: return ENOENT; | |
322 | case ERROR_DISK_FULL: return ENOSPC; | |
323 | } | |
324 | return EIO; /* better ?? */ | |
325 | } | |
326 | static inline int wmidi_fileexists (const char *path) { | |
327 | BPTR fd = Open((const STRPTR)path, MODE_OLDFILE); | |
328 | if (!fd) return 0; | |
329 | Close(fd); return 1; | |
330 | } | |
331 | static inline BPTR wmidi_open_write (const char *path) { | |
332 | return Open((const STRPTR) path, MODE_NEWFILE); | |
333 | } | |
334 | static inline LONG wmidi_close (BPTR fd) { | |
335 | return Close(fd); | |
336 | } | |
337 | static inline LONG wmidi_seekset (BPTR fd, LONG ofs) { | |
338 | return Seek(fd, ofs, OFFSET_BEGINNING); | |
339 | } | |
340 | static LONG wmidi_write (BPTR fd, /*const*/ void *buf, LONG size) { | |
341 | LONG written = 0, result; | |
342 | unsigned char *p = (unsigned char *)buf; | |
343 | while (written < size) { | |
344 | result = Write(fd, p + written, size - written); | |
345 | if (result < 0) return result; | |
346 | written += result; | |
347 | } | |
348 | return written; | |
349 | } | |
350 | ||
351 | #else /* common posix case */ | |
352 | static int audio_fd = -1; | |
353 | #define WM_IS_BADF(_fd) ((_fd)<0) | |
354 | #define WM_BADF -1 | |
355 | static inline int wmidi_fileexists (const char *path) { | |
356 | struct stat st; | |
357 | return (stat(path, &st) == 0); | |
358 | } | |
359 | static inline int wmidi_open_write (const char *path) { | |
360 | return open(path, (O_RDWR | O_CREAT | O_TRUNC), (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)); | |
361 | } | |
362 | static inline int wmidi_close (int fd) { | |
363 | return close(fd); | |
364 | } | |
365 | static inline off_t wmidi_seekset (int fd, off_t ofs) { | |
366 | return lseek(fd, ofs, SEEK_SET); | |
367 | } | |
368 | static inline ssize_t wmidi_write (int fd, const void *buf, size_t size) { | |
369 | return write(fd, buf, size); | |
370 | } | |
371 | #endif | |
212 | 372 | |
213 | 373 | static void pause_output_nop(void) { |
214 | 374 | } |
221 | 381 | static char midi_file[1024]; |
222 | 382 | |
223 | 383 | static int write_midi_output(void *output_data, int output_size) { |
224 | #ifdef __DJGPP__ | |
225 | struct ffblk f; | |
226 | #else | |
227 | struct stat st; | |
228 | #endif | |
229 | ||
230 | 384 | if (midi_file[0] == '\0') |
231 | 385 | return (-1); |
232 | 386 | |
233 | 387 | /* |
234 | 388 | * Test if file already exists |
235 | 389 | */ |
236 | #ifdef __DJGPP__ | |
237 | if (findfirst(midi_file, &f, FA_ARCH | FA_RDONLY) == 0) { | |
238 | #else | |
239 | if (stat(midi_file, &st) == 0) { | |
240 | #endif | |
390 | if (wmidi_fileexists(midi_file)) { | |
241 | 391 | fprintf(stderr, "\rError: %s already exists\r\n", midi_file); |
242 | 392 | return (-1); |
243 | 393 | } |
244 | 394 | |
245 | #if defined(_WIN32) || defined(__DJGPP__) | |
246 | audio_fd = open(midi_file, (O_RDWR | O_CREAT | O_TRUNC | O_BINARY), 0664); | |
247 | #else | |
248 | audio_fd = open(midi_file, (O_RDWR | O_CREAT | O_TRUNC), | |
249 | (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)); | |
250 | #endif | |
251 | if (audio_fd < 0) { | |
252 | fprintf(stderr, "Error: unable to open file for writing (%s)\r\n", strerror(errno)); | |
395 | audio_fd = wmidi_open_write(midi_file); | |
396 | if (WM_IS_BADF(audio_fd)) { | |
397 | fprintf(stderr, "Error: unable to open file for writing (%s)\r\n", strerror(wmidi_geterrno())); | |
253 | 398 | return (-1); |
254 | 399 | } |
255 | 400 | |
256 | if (write(audio_fd, output_data, output_size) < 0) { | |
257 | fprintf(stderr, "\nERROR: failed writing midi (%s)\r\n", strerror(errno)); | |
258 | close(audio_fd); | |
259 | audio_fd = -1; | |
401 | if (wmidi_write(audio_fd, output_data, output_size) < 0) { | |
402 | fprintf(stderr, "\nERROR: failed writing midi (%s)\r\n", strerror(wmidi_geterrno())); | |
403 | wmidi_close(audio_fd); | |
404 | audio_fd = WM_BADF; | |
260 | 405 | return (-1); |
261 | 406 | } |
262 | 407 | |
263 | close(audio_fd); | |
264 | audio_fd = -1; | |
408 | wmidi_close(audio_fd); | |
409 | audio_fd = WM_BADF; | |
265 | 410 | return (0); |
266 | 411 | } |
267 | 412 | |
295 | 440 | if (wav_file[0] == '\0') |
296 | 441 | return (-1); |
297 | 442 | |
298 | #if defined(_WIN32) || defined(__DJGPP__) | |
299 | audio_fd = open(wav_file, (O_RDWR | O_CREAT | O_TRUNC | O_BINARY), 0664); | |
300 | #else | |
301 | audio_fd = open(wav_file, (O_RDWR | O_CREAT | O_TRUNC), | |
302 | (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)); | |
303 | #endif | |
304 | if (audio_fd < 0) { | |
305 | fprintf(stderr, "Error: unable to open file for writing (%s)\r\n", strerror(errno)); | |
443 | audio_fd = wmidi_open_write(wav_file); | |
444 | if (WM_IS_BADF(audio_fd)) { | |
445 | fprintf(stderr, "Error: unable to open file for writing (%s)\r\n", strerror(wmidi_geterrno())); | |
306 | 446 | return (-1); |
307 | 447 | } else { |
308 | 448 | uint32_t bytes_per_sec; |
317 | 457 | wav_hdr[31] = (bytes_per_sec >> 24) & 0xFF; |
318 | 458 | } |
319 | 459 | |
320 | if (write(audio_fd, &wav_hdr, 44) < 0) { | |
321 | fprintf(stderr, "ERROR: failed writing wav header (%s)\r\n", strerror(errno)); | |
322 | close(audio_fd); | |
323 | audio_fd = -1; | |
460 | if (wmidi_write(audio_fd, &wav_hdr, 44) < 0) { | |
461 | fprintf(stderr, "ERROR: failed writing wav header (%s)\r\n", strerror(wmidi_geterrno())); | |
462 | wmidi_close(audio_fd); | |
463 | audio_fd = WM_BADF; | |
324 | 464 | return (-1); |
325 | 465 | } |
326 | 466 | |
341 | 481 | swp[i] = (swp[i] << 8) | (swp[i] >> 8); |
342 | 482 | } |
343 | 483 | #endif |
344 | if (write(audio_fd, output_data, output_size) < 0) { | |
345 | fprintf(stderr, "\nERROR: failed writing wav (%s)\r\n", strerror(errno)); | |
346 | close(audio_fd); | |
347 | audio_fd = -1; | |
484 | if (wmidi_write(audio_fd, output_data, output_size) < 0) { | |
485 | fprintf(stderr, "\nERROR: failed writing wav (%s)\r\n", strerror(wmidi_geterrno())); | |
486 | wmidi_close(audio_fd); | |
487 | audio_fd = WM_BADF; | |
348 | 488 | return (-1); |
349 | 489 | } |
350 | 490 | |
354 | 494 | |
355 | 495 | static void close_wav_output(void) { |
356 | 496 | uint8_t wav_count[4]; |
357 | if (audio_fd < 0) | |
497 | if (WM_IS_BADF(audio_fd)) | |
358 | 498 | return; |
359 | 499 | |
360 | 500 | printf("Finishing and closing wav output\r"); |
362 | 502 | wav_count[1] = (wav_size >> 8) & 0xFF; |
363 | 503 | wav_count[2] = (wav_size >> 16) & 0xFF; |
364 | 504 | wav_count[3] = (wav_size >> 24) & 0xFF; |
365 | lseek(audio_fd, 40, SEEK_SET); | |
366 | if (write(audio_fd, &wav_count, 4) < 0) { | |
367 | fprintf(stderr, "\nERROR: failed writing wav (%s)\r\n", strerror(errno)); | |
505 | wmidi_seekset(audio_fd, 40); | |
506 | if (wmidi_write(audio_fd, &wav_count, 4) < 0) { | |
507 | fprintf(stderr, "\nERROR: failed writing wav (%s)\r\n", strerror(wmidi_geterrno())); | |
368 | 508 | goto end; |
369 | 509 | } |
370 | 510 | |
373 | 513 | wav_count[1] = (wav_size >> 8) & 0xFF; |
374 | 514 | wav_count[2] = (wav_size >> 16) & 0xFF; |
375 | 515 | wav_count[3] = (wav_size >> 24) & 0xFF; |
376 | lseek(audio_fd, 4, SEEK_SET); | |
377 | if (write(audio_fd, &wav_count, 4) < 0) { | |
378 | fprintf(stderr, "\nERROR: failed writing wav (%s)\r\n", strerror(errno)); | |
516 | wmidi_seekset(audio_fd, 4); | |
517 | if (wmidi_write(audio_fd, &wav_count, 4) < 0) { | |
518 | fprintf(stderr, "\nERROR: failed writing wav (%s)\r\n", strerror(wmidi_geterrno())); | |
379 | 519 | goto end; |
380 | 520 | } |
381 | 521 | |
382 | 522 | end: printf("\n"); |
383 | if (audio_fd >= 0) | |
384 | close(audio_fd); | |
385 | audio_fd = -1; | |
523 | if (!WM_IS_BADF(audio_fd)) | |
524 | wmidi_close(audio_fd); | |
525 | audio_fd = WM_BADF; | |
386 | 526 | } |
387 | 527 | |
388 | 528 | #if (defined _WIN32) || (defined __CYGWIN__) |
521 | 661 | HeapFree(GetProcessHeap(), 0, mm_blocks); |
522 | 662 | hWaveOut = NULL; |
523 | 663 | mm_blocks = NULL; |
664 | } | |
665 | ||
666 | #elif (defined(__OS2__) || defined(__EMX__)) && defined(AUDIODRV_OS2DART) | |
667 | /* based on Dart code originally written by Kevin Langman for XMP */ | |
668 | ||
669 | #define open_audio_output open_dart_output | |
670 | static int write_dart_output (int8_t *output_data, int output_size); | |
671 | static void close_dart_output (void); | |
672 | ||
673 | #define BUFFERCOUNT 4 | |
674 | ||
675 | static MCI_MIX_BUFFER MixBuffers[BUFFERCOUNT]; | |
676 | static MCI_MIXSETUP_PARMS MixSetupParms; | |
677 | static MCI_BUFFER_PARMS BufferParms; | |
678 | static MCI_GENERIC_PARMS GenericParms; | |
679 | ||
680 | static ULONG DeviceID = 0; | |
681 | static ULONG bsize = 16; | |
682 | static short next = 2; | |
683 | static short ready = 1; | |
684 | ||
685 | static HMTX dart_mutex; | |
686 | ||
687 | /* Buffer update thread (created and called by DART) */ | |
688 | static LONG APIENTRY OS2_Dart_UpdateBuffers | |
689 | (ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags) { | |
690 | ||
691 | if ((ulFlags == MIX_WRITE_COMPLETE) || | |
692 | ((ulFlags == (MIX_WRITE_COMPLETE | MIX_STREAM_ERROR)) && | |
693 | (ulStatus == ERROR_DEVICE_UNDERRUN))) { | |
694 | DosRequestMutexSem(dart_mutex, SEM_INDEFINITE_WAIT); | |
695 | ready++; | |
696 | DosReleaseMutexSem(dart_mutex); | |
697 | } | |
698 | return (TRUE); | |
699 | } | |
700 | ||
701 | static int | |
702 | open_dart_output(void) { | |
703 | int i; | |
704 | MCI_AMP_OPEN_PARMS AmpOpenParms; | |
705 | ||
706 | if (DosCreateMutexSem(NULL, &dart_mutex, 0, 0) != NO_ERROR) { | |
707 | fprintf(stderr, "Failed creating a MutexSem.\r\n"); | |
708 | return (-1); | |
709 | } | |
710 | ||
711 | /* compute a size for circa 1/4" of playback. */ | |
712 | bsize = rate >> 2; | |
713 | bsize <<= 1; /* stereo */ | |
714 | bsize <<= 1; /* 16 bit */ | |
715 | for (i = 15; i >= 12; i--) { | |
716 | if (bsize & (1 << i)) | |
717 | break; | |
718 | } | |
719 | bsize = (1 << i); | |
720 | /* make sure buffer is not greater than 64 Kb: DART can't handle it. */ | |
721 | if (bsize > 65536) | |
722 | bsize = 65536; | |
723 | ||
724 | MixBuffers[0].pBuffer = NULL; /* marker */ | |
725 | memset(&GenericParms, 0, sizeof(MCI_GENERIC_PARMS)); | |
726 | ||
727 | /* open AMP device */ | |
728 | memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS)); | |
729 | AmpOpenParms.usDeviceID = 0; | |
730 | ||
731 | AmpOpenParms.pszDeviceType = | |
732 | (PSZ) MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX, 0); /* 0: default waveaudio device */ | |
733 | ||
734 | if(mciSendCommand(0, MCI_OPEN, MCI_WAIT|MCI_OPEN_TYPE_ID|MCI_OPEN_SHAREABLE, | |
735 | (PVOID) &AmpOpenParms, 0) != MCIERR_SUCCESS) { | |
736 | fprintf(stderr, "Failed opening DART audio device\r\n"); | |
737 | return (-1); | |
738 | } | |
739 | ||
740 | DeviceID = AmpOpenParms.usDeviceID; | |
741 | ||
742 | /* setup playback parameters */ | |
743 | memset(&MixSetupParms, 0, sizeof(MCI_MIXSETUP_PARMS)); | |
744 | ||
745 | MixSetupParms.ulBitsPerSample = 16; | |
746 | MixSetupParms.ulFormatTag = MCI_WAVE_FORMAT_PCM; | |
747 | MixSetupParms.ulSamplesPerSec = rate; | |
748 | MixSetupParms.ulChannels = 2; | |
749 | MixSetupParms.ulFormatMode = MCI_PLAY; | |
750 | MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; | |
751 | MixSetupParms.pmixEvent = OS2_Dart_UpdateBuffers; | |
752 | ||
753 | if (mciSendCommand(DeviceID, MCI_MIXSETUP, | |
754 | MCI_WAIT | MCI_MIXSETUP_INIT, | |
755 | (PVOID) & MixSetupParms, 0) != MCIERR_SUCCESS) { | |
756 | ||
757 | mciSendCommand(DeviceID, MCI_CLOSE, MCI_WAIT, | |
758 | (PVOID) & GenericParms, 0); | |
759 | fprintf(stderr, "Failed DART mixer setup\r\n"); | |
760 | return (-1); | |
761 | } | |
762 | ||
763 | /*bsize = MixSetupParms.ulBufferSize;*/ | |
764 | /*printf("Dart Buffer Size = %lu\n", bsize);*/ | |
765 | ||
766 | BufferParms.ulNumBuffers = BUFFERCOUNT; | |
767 | BufferParms.ulBufferSize = bsize; | |
768 | BufferParms.pBufList = MixBuffers; | |
769 | ||
770 | if (mciSendCommand(DeviceID, MCI_BUFFER, | |
771 | MCI_WAIT | MCI_ALLOCATE_MEMORY, | |
772 | (PVOID) & BufferParms, 0) != MCIERR_SUCCESS) { | |
773 | fprintf(stderr, "DART Memory allocation error\r\n"); | |
774 | mciSendCommand(DeviceID, MCI_CLOSE, MCI_WAIT, | |
775 | (PVOID) & GenericParms, 0); | |
776 | return (-1); | |
777 | } | |
778 | ||
779 | for (i = 0; i < BUFFERCOUNT; i++) { | |
780 | MixBuffers[i].ulBufferLength = bsize; | |
781 | } | |
782 | ||
783 | /* Start Playback */ | |
784 | memset(MixBuffers[0].pBuffer, /*32767 */ 0, bsize); | |
785 | memset(MixBuffers[1].pBuffer, /*32767 */ 0, bsize); | |
786 | MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle, MixBuffers, 2); | |
787 | ||
788 | send_output = write_dart_output; | |
789 | close_output = close_dart_output; | |
790 | pause_output = pause_output_nop; | |
791 | resume_output = resume_output_nop; | |
792 | ||
793 | return (0); | |
794 | } | |
795 | ||
796 | static int | |
797 | write_dart_output (int8_t *output_data, int output_size) { | |
798 | static int idx = 0; | |
799 | ||
800 | if (idx + output_size > bsize) { | |
801 | do { | |
802 | DosRequestMutexSem(dart_mutex, SEM_INDEFINITE_WAIT); | |
803 | if (ready != 0) { | |
804 | DosReleaseMutexSem(dart_mutex); | |
805 | break; | |
806 | } | |
807 | DosReleaseMutexSem(dart_mutex); | |
808 | DosSleep(20); | |
809 | } while (TRUE); | |
810 | ||
811 | MixBuffers[next].ulBufferLength = idx; | |
812 | MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle, &(MixBuffers[next]), 1); | |
813 | ready--; | |
814 | next++; | |
815 | idx = 0; | |
816 | if (next == BUFFERCOUNT) { | |
817 | next = 0; | |
818 | } | |
819 | } | |
820 | memcpy(&((char *)MixBuffers[next].pBuffer)[idx], output_data, output_size); | |
821 | idx += output_size; | |
822 | return (0); | |
823 | } | |
824 | ||
825 | static void | |
826 | close_dart_output (void) { | |
827 | printf("Shutting down sound output\r\n"); | |
828 | if (MixBuffers[0].pBuffer) { | |
829 | mciSendCommand(DeviceID, MCI_BUFFER, | |
830 | MCI_WAIT | MCI_DEALLOCATE_MEMORY, &BufferParms, 0); | |
831 | MixBuffers[0].pBuffer = NULL; | |
832 | } | |
833 | if (DeviceID) { | |
834 | mciSendCommand(DeviceID, MCI_CLOSE, MCI_WAIT, | |
835 | (PVOID) &GenericParms, 0); | |
836 | DeviceID = 0; | |
837 | } | |
524 | 838 | } |
525 | 839 | |
526 | 840 | #elif defined(__DJGPP__) && defined(AUDIODRV_DOSSB) |
692 | 1006 | return 0; |
693 | 1007 | } |
694 | 1008 | |
1009 | #elif defined(WILDMIDI_AMIGA) && defined(AUDIODRV_AHI) | |
1010 | ||
1011 | /* Driver for output to native Amiga AHI device: | |
1012 | * Written by Szilárd Biró <col.lawrence@gmail.com>, loosely based | |
1013 | * on an old AOS4 version by Fredrik Wikstrom <fredrik@a500.org> | |
1014 | */ | |
1015 | ||
1016 | #define BUFFERSIZE (4 << 10) | |
1017 | ||
1018 | static struct MsgPort *AHImp = NULL; | |
1019 | static struct AHIRequest *AHIReq[2] = { NULL, NULL }; | |
1020 | static int active = 0; | |
1021 | static int8_t *AHIBuf[2] = { NULL, NULL }; | |
1022 | ||
1023 | #define open_audio_output open_ahi_output | |
1024 | static int write_ahi_output(int8_t *output_data, int output_size); | |
1025 | static void close_ahi_output(void); | |
1026 | ||
1027 | static int open_ahi_output(void) { | |
1028 | AHImp = CreateMsgPort(); | |
1029 | if (AHImp) { | |
1030 | AHIReq[0] = (struct AHIRequest *)CreateIORequest(AHImp, sizeof(struct AHIRequest)); | |
1031 | if (AHIReq[0]) { | |
1032 | AHIReq[0]->ahir_Version = 4; | |
1033 | AHIReq[1] = AllocVec(sizeof(struct AHIRequest), MEMF_PUBLIC); | |
1034 | if (AHIReq[1]) { | |
1035 | if (!OpenDevice(AHINAME, AHI_DEFAULT_UNIT, (struct IORequest *)AHIReq[0], 0)) { | |
1036 | /*AHIReq[0]->ahir_Std.io_Message.mn_Node.ln_Pri = 0;*/ | |
1037 | AHIReq[0]->ahir_Std.io_Command = CMD_WRITE; | |
1038 | AHIReq[0]->ahir_Std.io_Data = NULL; | |
1039 | AHIReq[0]->ahir_Std.io_Offset = 0; | |
1040 | AHIReq[0]->ahir_Frequency = rate; | |
1041 | AHIReq[0]->ahir_Type = AHIST_S16S;/* 16 bit stereo */ | |
1042 | AHIReq[0]->ahir_Volume = 0x10000; | |
1043 | AHIReq[0]->ahir_Position = 0x8000; | |
1044 | CopyMem(AHIReq[0], AHIReq[1], sizeof(struct AHIRequest)); | |
1045 | ||
1046 | AHIBuf[0] = AllocVec(BUFFERSIZE, MEMF_PUBLIC | MEMF_CLEAR); | |
1047 | if (AHIBuf[0]) { | |
1048 | AHIBuf[1] = AllocVec(BUFFERSIZE, MEMF_PUBLIC | MEMF_CLEAR); | |
1049 | if (AHIBuf[1]) { | |
1050 | send_output = write_ahi_output; | |
1051 | close_output = close_ahi_output; | |
1052 | pause_output = pause_output_nop; | |
1053 | resume_output = resume_output_nop; | |
1054 | return (0); | |
1055 | } | |
1056 | } | |
1057 | } | |
1058 | } | |
1059 | } | |
1060 | } | |
1061 | ||
1062 | close_ahi_output(); | |
1063 | fprintf(stderr, "ERROR: Unable to open AHI output\r\n"); | |
1064 | return (-1); | |
1065 | } | |
1066 | ||
1067 | static int write_ahi_output(int8_t *output_data, int output_size) { | |
1068 | int chunk; | |
1069 | while (output_size > 0) { | |
1070 | if (AHIReq[active]->ahir_Std.io_Data) { | |
1071 | WaitIO((struct IORequest *) AHIReq[active]); | |
1072 | } | |
1073 | chunk = (output_size < BUFFERSIZE)? output_size : BUFFERSIZE; | |
1074 | memcpy(AHIBuf[active], output_data, chunk); | |
1075 | output_size -= chunk; | |
1076 | output_data += chunk; | |
1077 | ||
1078 | AHIReq[active]->ahir_Std.io_Data = AHIBuf[active]; | |
1079 | AHIReq[active]->ahir_Std.io_Length = chunk; | |
1080 | AHIReq[active]->ahir_Link = !CheckIO((struct IORequest *) AHIReq[active ^ 1]) ? AHIReq[active ^ 1] : NULL; | |
1081 | SendIO((struct IORequest *)AHIReq[active]); | |
1082 | active ^= 1; | |
1083 | } | |
1084 | return (0); | |
1085 | } | |
1086 | ||
1087 | static void close_ahi_output(void) { | |
1088 | if (AHIReq[1]) { | |
1089 | AHIReq[0]->ahir_Link = NULL; /* in case we are linked to req[0] */ | |
1090 | if (!CheckIO((struct IORequest *) AHIReq[1])) { | |
1091 | AbortIO((struct IORequest *) AHIReq[1]); | |
1092 | WaitIO((struct IORequest *) AHIReq[1]); | |
1093 | } | |
1094 | FreeVec(AHIReq[1]); | |
1095 | AHIReq[1] = NULL; | |
1096 | } | |
1097 | if (AHIReq[0]) { | |
1098 | if (!CheckIO((struct IORequest *) AHIReq[0])) { | |
1099 | AbortIO((struct IORequest *) AHIReq[0]); | |
1100 | WaitIO((struct IORequest *) AHIReq[0]); | |
1101 | } | |
1102 | if (AHIReq[0]->ahir_Std.io_Device) { | |
1103 | CloseDevice((struct IORequest *) AHIReq[0]); | |
1104 | AHIReq[0]->ahir_Std.io_Device = NULL; | |
1105 | } | |
1106 | DeleteIORequest((struct IORequest *) AHIReq[0]); | |
1107 | AHIReq[0] = NULL; | |
1108 | } | |
1109 | if (AHImp) { | |
1110 | DeleteMsgPort(AHImp); | |
1111 | AHImp = NULL; | |
1112 | } | |
1113 | if (AHIBuf[0]) { | |
1114 | FreeVec(AHIBuf[0]); | |
1115 | AHIBuf[0] = NULL; | |
1116 | } | |
1117 | if (AHIBuf[1]) { | |
1118 | FreeVec(AHIBuf[1]); | |
1119 | AHIBuf[1] = NULL; | |
1120 | } | |
1121 | } | |
1122 | ||
695 | 1123 | #else |
696 | 1124 | #ifdef AUDIODRV_ALSA |
697 | 1125 | |
1048 | 1476 | |
1049 | 1477 | #define open_audio_output open_noaudio_output |
1050 | 1478 | static int open_noaudio_output(void) { |
1479 | fprintf(stderr, "No audio output driver was selected at compile time.\r\n"); | |
1051 | 1480 | return -1; |
1052 | 1481 | } |
1053 | 1482 | |
1138 | 1567 | uint32_t apr_mins; |
1139 | 1568 | uint32_t apr_secs; |
1140 | 1569 | char modes[5]; |
1141 | // uint32_t count_diff = 0; | |
1142 | 1570 | uint8_t ch; |
1143 | uint8_t test_midi = 0; | |
1144 | uint8_t test_count = 0; | |
1571 | int test_midi = 0; | |
1572 | int test_count = 0; | |
1145 | 1573 | uint8_t *test_data; |
1146 | 1574 | uint8_t test_bank = 0; |
1147 | 1575 | uint8_t test_patch = 0; |
1148 | 1576 | static char spinner[] = "|/-\\"; |
1149 | 1577 | static int spinpoint = 0; |
1150 | 1578 | unsigned long int seek_to_sample; |
1151 | unsigned long int samples = 0; | |
1579 | uint32_t samples = 0; | |
1152 | 1580 | int inpause = 0; |
1153 | 1581 | char * ret_err = NULL; |
1154 | 1582 | long libraryver; |
1155 | 1583 | char * lyric = NULL; |
1156 | 1584 | char *last_lyric = NULL; |
1157 | uint32_t last_lyric_length = 0; | |
1585 | size_t last_lyric_length = 0; | |
1158 | 1586 | int8_t kareoke = 0; |
1159 | 1587 | #define MAX_LYRIC_CHAR 128 |
1160 | 1588 | char lyrics[MAX_LYRIC_CHAR + 1]; |
1161 | 1589 | #define MAX_DISPLAY_LYRICS 29 |
1162 | 1590 | char display_lyrics[MAX_DISPLAY_LYRICS + 1]; |
1163 | ||
1164 | unsigned long int play_from = 0.0; | |
1165 | unsigned long int play_to = 0.0; | |
1591 | ||
1592 | unsigned long int play_from = 0; | |
1593 | unsigned long int play_to = 0; | |
1166 | 1594 | |
1167 | 1595 | memset(lyrics,' ',MAX_LYRIC_CHAR); |
1168 | 1596 | memset(display_lyrics,' ',MAX_DISPLAY_LYRICS); |
1193 | 1621 | fprintf(stderr, "Error: bad rate %i.\n", res); |
1194 | 1622 | return (1); |
1195 | 1623 | } |
1196 | rate = res; | |
1624 | rate = (uint32_t) res; | |
1197 | 1625 | break; |
1198 | 1626 | case 'b': /* Reverb */ |
1199 | 1627 | mixer_options |= WM_MO_REVERB; |
1210 | 1638 | wav_file[sizeof(wav_file) - 1] = 0; |
1211 | 1639 | break; |
1212 | 1640 | case 'g': /* XMIDI Conversion */ |
1213 | WildMidi_SetCvtOption(WM_CO_XMI_TYPE, atoi(optarg)); | |
1641 | WildMidi_SetCvtOption(WM_CO_XMI_TYPE, (uint16_t) atoi(optarg)); | |
1214 | 1642 | break; |
1215 | 1643 | case 'f': /* MIDI-like Conversion */ |
1216 | WildMidi_SetCvtOption(WM_CO_FREQUENCY, atoi(optarg)); | |
1644 | WildMidi_SetCvtOption(WM_CO_FREQUENCY, (uint16_t) atoi(optarg)); | |
1217 | 1645 | break; |
1218 | 1646 | case 'x': /* MIDI Output */ |
1219 | 1647 | if (!*optarg) { |
1306 | 1734 | |
1307 | 1735 | printf("Converting %s\r\n", real_file); |
1308 | 1736 | if (WildMidi_ConvertToMidi(argv[optind], &data, &size) < 0) { |
1309 | fprintf(stderr, "Conversion failed.\r\n"); | |
1737 | fprintf(stderr, "Conversion failed: %s.\r\n", WildMidi_GetError()); | |
1738 | WildMidi_ClearError(); | |
1310 | 1739 | return (1); |
1311 | 1740 | } |
1312 | 1741 | |
1338 | 1767 | (libraryver>> 8) & 255, |
1339 | 1768 | (libraryver ) & 255); |
1340 | 1769 | if (WildMidi_Init(config_file, rate, mixer_options) == -1) { |
1770 | fprintf(stderr, "%s\r\n", WildMidi_GetError()); | |
1771 | WildMidi_ClearError(); | |
1341 | 1772 | return (1); |
1342 | 1773 | } |
1343 | 1774 | |
1354 | 1785 | } |
1355 | 1786 | |
1356 | 1787 | wm_inittty(); |
1788 | #ifdef WILDMIDI_AMIGA | |
1789 | amiga_sysinit(); | |
1790 | #endif | |
1357 | 1791 | |
1358 | 1792 | WildMidi_MasterVolume(master_volume); |
1359 | 1793 | |
1407 | 1841 | |
1408 | 1842 | memset(lyrics,' ',MAX_LYRIC_CHAR); |
1409 | 1843 | memset(display_lyrics,' ',MAX_DISPLAY_LYRICS); |
1410 | ||
1844 | ||
1411 | 1845 | if (play_from != 0) { |
1412 | 1846 | WildMidi_FastSeek(midi_ptr, &play_from); |
1413 | 1847 | if (play_to < play_from) { |
1414 | 1848 | // Ignore --playto if set less than --playfrom |
1415 | } play_to = 0; | |
1849 | play_to = 0; | |
1850 | } | |
1416 | 1851 | } |
1417 | 1852 | |
1418 | 1853 | while (1) { |
1419 | #if 0 | |
1420 | count_diff = wm_info->approx_total_samples | |
1421 | - wm_info->current_sample; | |
1422 | ||
1423 | if (count_diff == 0) | |
1424 | break; | |
1425 | #endif | |
1426 | 1854 | ch = 0; |
1427 | 1855 | #ifdef _WIN32 |
1428 | 1856 | if (_kbhit()) { |
1429 | 1857 | ch = _getch(); |
1430 | 1858 | _putch(ch); |
1431 | 1859 | } |
1432 | #elif defined(__DJGPP__) | |
1860 | #elif defined(__DJGPP__) || defined(__OS2__) || defined(__EMX__) | |
1433 | 1861 | if (kbhit()) { |
1434 | 1862 | ch = getch(); |
1435 | 1863 | putch(ch); |
1436 | 1864 | } |
1865 | #elif defined(WILDMIDI_AMIGA) | |
1866 | amiga_getch (&ch); | |
1437 | 1867 | #else |
1438 | 1868 | if (read(STDIN_FILENO, &ch, 1) != 1) |
1439 | 1869 | ch = 0; |
1563 | 1993 | pro_secs = (wm_info->current_sample % (rate * 60)) / rate; |
1564 | 1994 | fprintf(stderr, |
1565 | 1995 | "%s [%s] [%3i] [%2um %2us Processed] [%2u%%] P \r", |
1566 | display_lyrics, modes, master_volume, pro_mins, | |
1996 | display_lyrics, modes, (int)master_volume, pro_mins, | |
1567 | 1997 | pro_secs, perc_play); |
1568 | 1998 | msleep(5); |
1569 | 1999 | continue; |
1570 | 2000 | } |
1571 | 2001 | |
1572 | ||
1573 | 2002 | if (play_to != 0) { |
1574 | 2003 | if ((wm_info->current_sample + 4096) <= play_to) { |
1575 | 2004 | samples = 16384; |
1576 | 2005 | } else { |
1577 | 2006 | samples = (play_to - wm_info->current_sample) << 2; |
1578 | if (samples <= 0) { | |
2007 | if (!samples) { | |
1579 | 2008 | // We are at or past where we wanted to play to |
1580 | 2009 | break; |
1581 | 2010 | } |
1582 | ||
1583 | 2011 | } |
1584 | } else { | |
2012 | } | |
2013 | else { | |
1585 | 2014 | samples = 16384; |
1586 | 2015 | } |
1587 | 2016 | res = WildMidi_GetOutput(midi_ptr, output_buffer, samples); |
1588 | // (count_diff >= 4096)? 16384 : (count_diff * 4)); | |
2017 | ||
1589 | 2018 | if (res <= 0) |
1590 | 2019 | break; |
1591 | 2020 | |
1615 | 2044 | pro_secs = (wm_info->current_sample % (rate * 60)) / rate; |
1616 | 2045 | fprintf(stderr, |
1617 | 2046 | "%s [%s] [%3i] [%2um %2us Processed] [%2u%%] %c \r", |
1618 | display_lyrics, modes, master_volume, pro_mins, | |
2047 | display_lyrics, modes, (int)master_volume, pro_mins, | |
1619 | 2048 | pro_secs, perc_play, spinner[spinpoint++ % 4]); |
1620 | 2049 | |
1621 | 2050 | if (send_output(output_buffer, res) < 0) { |
1635 | 2064 | end1: memset(output_buffer, 0, 16384); |
1636 | 2065 | send_output(output_buffer, 16384); |
1637 | 2066 | msleep(5); |
1638 | #if 0/*#ifdef AUDIODRV_OPENAL*/ | |
1639 | /* FIXME: Delay needed in OPENAL before exiting to complete the song. */ | |
1640 | msleep(1000); | |
1641 | #endif | |
1642 | 2067 | end2: close_output(); |
1643 | 2068 | free(output_buffer); |
1644 | 2069 | if (WildMidi_Shutdown() == -1) { |
1654 | 2079 | |
1655 | 2080 | /* helper / replacement functions: */ |
1656 | 2081 | |
1657 | #if !defined(_WIN32) && !defined(__DJGPP__) | |
2082 | #if !(defined(_WIN32) || defined(__DJGPP__) || defined(WILDMIDI_AMIGA) || defined(__OS2__) || defined(__EMX__)) | |
1658 | 2083 | static int msleep(unsigned long milisec) { |
1659 | 2084 | struct timespec req = { 0, 0 }; |
1660 | 2085 | time_t sec = (int) (milisec / 1000); |
0 | # WildMIDI pkg-config file | |
1 | ||
2 | prefix=@WILDMIDILIB_PREFIX@ | |
3 | exec_prefix=${prefix} | |
4 | libdir=${exec_prefix}/@WILDMIDILIB_LIBDIR@ | |
5 | includedir=${exec_prefix}/include | |
6 | ||
7 | Name: WildMIDI | |
8 | Description: software synthesizer library | |
9 | Version: @WILDMIDI_VERSION@ | |
10 | URL: https://www.mindwerks.net/projects/wildmidi/ | |
11 | ||
12 | Libs: -L${libdir} -lWildMidi | |
13 | Libs.private: -lm | |
14 | Cflags: -I${includedir} |
26 | 26 | |
27 | 27 | #include <stdint.h> |
28 | 28 | #include <errno.h> |
29 | #include <fcntl.h> | |
30 | 29 | #include <math.h> |
31 | #ifndef _WIN32 | |
32 | #include <pwd.h> | |
33 | #include <strings.h> | |
34 | #include <unistd.h> | |
35 | #endif | |
36 | 30 | #include <stdarg.h> |
37 | 31 | #include <stdio.h> |
38 | 32 | #include <stdlib.h> |
39 | 33 | #include <string.h> |
40 | #include <sys/stat.h> | |
41 | #include <sys/types.h> | |
42 | ||
43 | #ifdef _WIN32 | |
44 | #include <windows.h> | |
45 | #include <tchar.h> | |
46 | #undef strcasecmp | |
47 | #define strcasecmp _stricmp | |
48 | #undef strncasecmp | |
49 | #define strncasecmp _tcsnicmp | |
50 | #endif | |
51 | 34 | |
52 | 35 | #include "wm_error.h" |
53 | 36 | #include "file_io.h" |
272 | 255 | static inline int wm_isdigit(int c) { |
273 | 256 | return (c >= '0' && c <= '9'); |
274 | 257 | } |
258 | static inline int wm_isupper(int c) { | |
259 | return (c >= 'A' && c <= 'Z'); | |
260 | } | |
261 | static inline int wm_tolower(int c) { | |
262 | return ((wm_isupper(c)) ? (c | ('a' - 'A')) : c); | |
263 | } | |
264 | #if 0 /* clang whines that these aren't used. */ | |
265 | static inline int wm_islower(int c) { | |
266 | return (c >= 'a' && c <= 'z'); | |
267 | } | |
268 | static inline int wm_toupper(int c) { | |
269 | return ((wm_islower(c)) ? (c & ~('a' - 'A')) : c); | |
270 | } | |
271 | #endif | |
272 | ||
273 | static int wm_strcasecmp(const char *s1, const char * s2) { | |
274 | const char * p1 = s1; | |
275 | const char * p2 = s2; | |
276 | char c1, c2; | |
277 | ||
278 | if (p1 == p2) return 0; | |
279 | do { | |
280 | c1 = wm_tolower (*p1++); | |
281 | c2 = wm_tolower (*p2++); | |
282 | if (c1 == '\0') break; | |
283 | } while (c1 == c2); | |
284 | return (int)(c1 - c2); | |
285 | } | |
286 | ||
287 | static int wm_strncasecmp(const char *s1, const char *s2, size_t n) { | |
288 | const char * p1 = s1; | |
289 | const char * p2 = s2; | |
290 | char c1, c2; | |
291 | ||
292 | if (p1 == p2 || n == 0) return 0; | |
293 | do { | |
294 | c1 = wm_tolower (*p1++); | |
295 | c2 = wm_tolower (*p2++); | |
296 | if (c1 == '\0' || c1 != c2) break; | |
297 | } while (--n > 0); | |
298 | return (int)(c1 - c2); | |
299 | } | |
275 | 300 | |
276 | 301 | #define TOKEN_CNT_INC 8 |
277 | 302 | static char** WM_LC_Tokenize_Line(char *line_data) { |
304 | 329 | token_data_length += TOKEN_CNT_INC; |
305 | 330 | token_data = realloc(token_data, token_data_length * sizeof(char *)); |
306 | 331 | if (token_data == NULL) { |
307 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM,"to parse config", errno); | |
332 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM,"to parse config", errno); | |
308 | 333 | return (NULL); |
309 | 334 | } |
310 | 335 | } |
328 | 353 | return (token_data); |
329 | 354 | } |
330 | 355 | |
331 | static int WM_LoadConfig(const char *config_file) { | |
356 | static int load_config(const char *config_file, const char *conf_dir) { | |
332 | 357 | uint32_t config_size = 0; |
333 | 358 | char *config_buffer = NULL; |
334 | 359 | const char *dir_end = NULL; |
346 | 371 | return (-1); |
347 | 372 | } |
348 | 373 | |
349 | dir_end = FIND_LAST_DIRSEP(config_file); | |
350 | if (dir_end) { | |
351 | config_dir = malloc((dir_end - config_file + 2)); | |
352 | if (config_dir == NULL) { | |
353 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse config", | |
354 | errno); | |
355 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
374 | if (conf_dir) { | |
375 | if (!(config_dir = wm_strdup(conf_dir))) { | |
376 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, errno); | |
356 | 377 | WM_FreePatches(); |
357 | 378 | free(config_buffer); |
358 | 379 | return (-1); |
359 | 380 | } |
360 | strncpy(config_dir, config_file, (dir_end - config_file + 1)); | |
361 | config_dir[dir_end - config_file + 1] = '\0'; | |
381 | } else { | |
382 | dir_end = FIND_LAST_DIRSEP(config_file); | |
383 | if (dir_end) { | |
384 | config_dir = malloc((dir_end - config_file + 2)); | |
385 | if (config_dir == NULL) { | |
386 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, errno); | |
387 | WM_FreePatches(); | |
388 | free(config_buffer); | |
389 | return (-1); | |
390 | } | |
391 | strncpy(config_dir, config_file, (dir_end - config_file + 1)); | |
392 | config_dir[dir_end - config_file + 1] = '\0'; | |
393 | } | |
362 | 394 | } |
363 | 395 | |
364 | 396 | config_ptr = 0; |
375 | 407 | config_buffer[config_ptr] = '\0'; |
376 | 408 | |
377 | 409 | if (config_ptr != line_start_ptr) { |
410 | _WM_Global_ErrorI = 0; /* because WM_LC_Tokenize_Line() can legitimately return NULL */ | |
378 | 411 | line_tokens = WM_LC_Tokenize_Line(&config_buffer[line_start_ptr]); |
379 | 412 | if (line_tokens) { |
380 | if (strcasecmp(line_tokens[0], "dir") == 0) { | |
413 | if (wm_strcasecmp(line_tokens[0], "dir") == 0) { | |
381 | 414 | free(config_dir); |
382 | 415 | if (!line_tokens[1]) { |
383 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(missing name in dir line)", 0); | |
384 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
416 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(missing name in dir line)", 0); | |
385 | 417 | WM_FreePatches(); |
386 | 418 | free(line_tokens); |
387 | 419 | free(config_buffer); |
388 | 420 | return (-1); |
389 | 421 | } else if (!(config_dir = wm_strdup(line_tokens[1]))) { |
390 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse config", errno); | |
391 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
422 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, errno); | |
392 | 423 | WM_FreePatches(); |
393 | 424 | free(line_tokens); |
394 | 425 | free(config_buffer); |
398 | 429 | config_dir[strlen(config_dir) + 1] = '\0'; |
399 | 430 | config_dir[strlen(config_dir)] = DIR_SEPARATOR_CHAR; |
400 | 431 | } |
401 | } else if (strcasecmp(line_tokens[0], "source") == 0) { | |
432 | } else if (wm_strcasecmp(line_tokens[0], "source") == 0) { | |
402 | 433 | char *new_config = NULL; |
403 | 434 | if (!line_tokens[1]) { |
404 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(missing name in source line)", 0); | |
405 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
435 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(missing name in source line)", 0); | |
406 | 436 | WM_FreePatches(); |
407 | 437 | free(line_tokens); |
408 | 438 | free(config_buffer); |
410 | 440 | } else if (!IS_ABSOLUTE_PATH(line_tokens[1]) && config_dir) { |
411 | 441 | new_config = malloc(strlen(config_dir) + strlen(line_tokens[1]) + 1); |
412 | 442 | if (new_config == NULL) { |
413 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse config", errno); | |
414 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
443 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, errno); | |
415 | 444 | WM_FreePatches(); |
416 | 445 | free(config_dir); |
417 | 446 | free(line_tokens); |
422 | 451 | strcpy(&new_config[strlen(config_dir)], line_tokens[1]); |
423 | 452 | } else { |
424 | 453 | if (!(new_config = wm_strdup(line_tokens[1]))) { |
425 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to parse config", errno); | |
426 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
454 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, errno); | |
427 | 455 | WM_FreePatches(); |
428 | 456 | free(line_tokens); |
429 | 457 | free(config_buffer); |
430 | 458 | return (-1); |
431 | 459 | } |
432 | 460 | } |
433 | if (WM_LoadConfig(new_config) == -1) { | |
461 | if (load_config(new_config, config_dir) == -1) { | |
434 | 462 | free(new_config); |
435 | 463 | free(line_tokens); |
436 | 464 | free(config_buffer); |
438 | 466 | return (-1); |
439 | 467 | } |
440 | 468 | free(new_config); |
441 | } else if (strcasecmp(line_tokens[0], "bank") == 0) { | |
469 | } else if (wm_strcasecmp(line_tokens[0], "bank") == 0) { | |
442 | 470 | if (!line_tokens[1] || !wm_isdigit(line_tokens[1][0])) { |
443 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in bank line)", 0); | |
444 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
471 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in bank line)", 0); | |
445 | 472 | WM_FreePatches(); |
446 | 473 | free(config_dir); |
447 | 474 | free(line_tokens); |
449 | 476 | return (-1); |
450 | 477 | } |
451 | 478 | patchid = (atoi(line_tokens[1]) & 0xFF) << 8; |
452 | } else if (strcasecmp(line_tokens[0], "drumset") == 0) { | |
479 | } else if (wm_strcasecmp(line_tokens[0], "drumset") == 0) { | |
453 | 480 | if (!line_tokens[1] || !wm_isdigit(line_tokens[1][0])) { |
454 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in drumset line)", 0); | |
455 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
481 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in drumset line)", 0); | |
456 | 482 | WM_FreePatches(); |
457 | 483 | free(config_dir); |
458 | 484 | free(line_tokens); |
460 | 486 | return (-1); |
461 | 487 | } |
462 | 488 | patchid = ((atoi(line_tokens[1]) & 0xFF) << 8) | 0x80; |
463 | } else if (strcasecmp(line_tokens[0], "reverb_room_width") == 0) { | |
489 | } else if (wm_strcasecmp(line_tokens[0], "reverb_room_width") == 0) { | |
464 | 490 | if (!line_tokens[1] || !wm_isdigit(line_tokens[1][0])) { |
465 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in reverb_room_width line)", 0); | |
466 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
491 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in reverb_room_width line)", 0); | |
467 | 492 | WM_FreePatches(); |
468 | 493 | free(config_dir); |
469 | 494 | free(line_tokens); |
472 | 497 | } |
473 | 498 | _WM_reverb_room_width = (float) atof(line_tokens[1]); |
474 | 499 | if (_WM_reverb_room_width < 1.0f) { |
475 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(reverb_room_width < 1 meter, setting to minimum of 1 meter)", 0); | |
500 | _WM_DEBUG_MSG("%s: reverb_room_width < 1 meter, setting to minimum of 1 meter", config_file); | |
476 | 501 | _WM_reverb_room_width = 1.0f; |
477 | 502 | } else if (_WM_reverb_room_width > 100.0f) { |
478 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(reverb_room_width > 100 meters, setting to maximum of 100 meters)", 0); | |
503 | _WM_DEBUG_MSG("%s: reverb_room_width > 100 meters, setting to maximum of 100 meters", config_file); | |
479 | 504 | _WM_reverb_room_width = 100.0f; |
480 | 505 | } |
481 | } else if (strcasecmp(line_tokens[0], "reverb_room_length") == 0) { | |
506 | } else if (wm_strcasecmp(line_tokens[0], "reverb_room_length") == 0) { | |
482 | 507 | if (!line_tokens[1] || !wm_isdigit(line_tokens[1][0])) { |
483 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in reverb_room_length line)", 0); | |
484 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, | |
485 | config_file, 0); | |
508 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in reverb_room_length line)", 0); | |
486 | 509 | WM_FreePatches(); |
487 | 510 | free(config_dir); |
488 | 511 | free(line_tokens); |
491 | 514 | } |
492 | 515 | _WM_reverb_room_length = (float) atof(line_tokens[1]); |
493 | 516 | if (_WM_reverb_room_length < 1.0f) { |
494 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(reverb_room_length < 1 meter, setting to minimum of 1 meter)", 0); | |
517 | _WM_DEBUG_MSG("%s: reverb_room_length < 1 meter, setting to minimum of 1 meter", config_file); | |
495 | 518 | _WM_reverb_room_length = 1.0f; |
496 | 519 | } else if (_WM_reverb_room_length > 100.0f) { |
497 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(reverb_room_length > 100 meters, setting to maximum of 100 meters)", 0); | |
520 | _WM_DEBUG_MSG("%s: reverb_room_length > 100 meters, setting to maximum of 100 meters", config_file); | |
498 | 521 | _WM_reverb_room_length = 100.0f; |
499 | 522 | } |
500 | } else if (strcasecmp(line_tokens[0], "reverb_listener_posx") == 0) { | |
523 | } else if (wm_strcasecmp(line_tokens[0], "reverb_listener_posx") == 0) { | |
501 | 524 | if (!line_tokens[1] || !wm_isdigit(line_tokens[1][0])) { |
502 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in reverb_listen_posx line)", 0); | |
503 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
525 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in reverb_listen_posx line)", 0); | |
504 | 526 | WM_FreePatches(); |
505 | 527 | free(config_dir); |
506 | 528 | free(line_tokens); |
510 | 532 | _WM_reverb_listen_posx = (float) atof(line_tokens[1]); |
511 | 533 | if ((_WM_reverb_listen_posx > _WM_reverb_room_width) |
512 | 534 | || (_WM_reverb_listen_posx < 0.0f)) { |
513 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(reverb_listen_posx set outside of room)", 0); | |
535 | _WM_DEBUG_MSG("%s: reverb_listen_posx set outside of room", config_file); | |
514 | 536 | _WM_reverb_listen_posx = _WM_reverb_room_width / 2.0f; |
515 | 537 | } |
516 | } else if (strcasecmp(line_tokens[0], | |
538 | } else if (wm_strcasecmp(line_tokens[0], | |
517 | 539 | "reverb_listener_posy") == 0) { |
518 | 540 | if (!line_tokens[1] || !wm_isdigit(line_tokens[1][0])) { |
519 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in reverb_listen_posy line)", 0); | |
520 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
541 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in reverb_listen_posy line)", 0); | |
521 | 542 | WM_FreePatches(); |
522 | 543 | free(config_dir); |
523 | 544 | free(line_tokens); |
527 | 548 | _WM_reverb_listen_posy = (float) atof(line_tokens[1]); |
528 | 549 | if ((_WM_reverb_listen_posy > _WM_reverb_room_width) |
529 | 550 | || (_WM_reverb_listen_posy < 0.0f)) { |
530 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(reverb_listen_posy set outside of room)", 0); | |
551 | _WM_DEBUG_MSG("%s: reverb_listen_posy set outside of room", config_file); | |
531 | 552 | _WM_reverb_listen_posy = _WM_reverb_room_length * 0.75f; |
532 | 553 | } |
533 | } else if (strcasecmp(line_tokens[0], "guspat_editor_author_cant_read_so_fix_release_time_for_me") == 0) { | |
554 | } else if (wm_strcasecmp(line_tokens[0], "guspat_editor_author_cant_read_so_fix_release_time_for_me") == 0) { | |
534 | 555 | _WM_fix_release = 1; |
535 | } else if (strcasecmp(line_tokens[0], "auto_amp") == 0) { | |
556 | } else if (wm_strcasecmp(line_tokens[0], "auto_amp") == 0) { | |
536 | 557 | _WM_auto_amp = 1; |
537 | } else if (strcasecmp(line_tokens[0], "auto_amp_with_amp") == 0) { | |
558 | } else if (wm_strcasecmp(line_tokens[0], "auto_amp_with_amp") == 0) { | |
538 | 559 | _WM_auto_amp = 1; |
539 | 560 | _WM_auto_amp_with_amp = 1; |
540 | 561 | } else if (wm_isdigit(line_tokens[0][0])) { |
543 | 564 | if (_WM_patch[(patchid & 0x7F)] == NULL) { |
544 | 565 | _WM_patch[(patchid & 0x7F)] = malloc(sizeof(struct _patch)); |
545 | 566 | if (_WM_patch[(patchid & 0x7F)] == NULL) { |
546 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, errno); | |
547 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
567 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, errno); | |
548 | 568 | WM_FreePatches(); |
549 | 569 | free(config_dir); |
550 | 570 | free(line_tokens); |
576 | 596 | } |
577 | 597 | if (tmp_patch->next == NULL) { |
578 | 598 | if ((tmp_patch->next = malloc(sizeof(struct _patch))) == NULL) { |
579 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, 0); | |
580 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
599 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, 0); | |
581 | 600 | WM_FreePatches(); |
582 | 601 | free(config_dir); |
583 | 602 | free(line_tokens); |
604 | 623 | tmp_patch->next = malloc( |
605 | 624 | sizeof(struct _patch)); |
606 | 625 | if (tmp_patch->next == NULL) { |
607 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, errno); | |
608 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
626 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, errno); | |
609 | 627 | WM_FreePatches(); |
610 | 628 | free(config_dir); |
611 | 629 | free(line_tokens); |
625 | 643 | } |
626 | 644 | } |
627 | 645 | if (!line_tokens[1]) { |
628 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(missing name in patch line)", 0); | |
629 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
646 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(missing name in patch line)", 0); | |
630 | 647 | WM_FreePatches(); |
631 | 648 | free(config_dir); |
632 | 649 | free(line_tokens); |
635 | 652 | } else if (!IS_ABSOLUTE_PATH(line_tokens[1]) && config_dir) { |
636 | 653 | tmp_patch->filename = malloc(strlen(config_dir) + strlen(line_tokens[1]) + 5); |
637 | 654 | if (tmp_patch->filename == NULL) { |
638 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, 0); | |
639 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
655 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, 0); | |
640 | 656 | WM_FreePatches(); |
641 | 657 | free(config_dir); |
642 | 658 | free(line_tokens); |
647 | 663 | strcat(tmp_patch->filename, line_tokens[1]); |
648 | 664 | } else { |
649 | 665 | if (!(tmp_patch->filename = wm_strdup(line_tokens[1]))) { |
650 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, NULL, 0); | |
651 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LOAD, config_file, 0); | |
666 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, config_file, 0); | |
652 | 667 | WM_FreePatches(); |
653 | 668 | free(config_dir); |
654 | 669 | free(line_tokens); |
656 | 671 | return (-1); |
657 | 672 | } |
658 | 673 | } |
659 | if (strncasecmp(&tmp_patch->filename[strlen(tmp_patch->filename) - 4], ".pat", 4) != 0) { | |
674 | if (wm_strncasecmp(&tmp_patch->filename[strlen(tmp_patch->filename) - 4], ".pat", 4) != 0) { | |
660 | 675 | strcat(tmp_patch->filename, ".pat"); |
661 | 676 | } |
662 | 677 | tmp_patch->env[0].set = 0x00; |
670 | 685 | |
671 | 686 | token_count = 0; |
672 | 687 | while (line_tokens[token_count]) { |
673 | if (strncasecmp(line_tokens[token_count], "amp=", 4) == 0) { | |
688 | if (wm_strncasecmp(line_tokens[token_count], "amp=", 4) == 0) { | |
674 | 689 | if (!wm_isdigit(line_tokens[token_count][4])) { |
675 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in patch line)", 0); | |
690 | _WM_DEBUG_MSG("%s: syntax error in patch line for %s", config_file, "amp="); | |
676 | 691 | } else { |
677 | 692 | tmp_patch->amp = (atoi(&line_tokens[token_count][4]) << 10) / 100; |
678 | 693 | } |
679 | } else if (strncasecmp(line_tokens[token_count], "note=", 5) == 0) { | |
694 | } else if (wm_strncasecmp(line_tokens[token_count], "note=", 5) == 0) { | |
680 | 695 | if (!wm_isdigit(line_tokens[token_count][5])) { |
681 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in patch line)", 0); | |
696 | _WM_DEBUG_MSG("%s: syntax error in patch line for %s", config_file, "note="); | |
682 | 697 | } else { |
683 | 698 | tmp_patch->note = atoi(&line_tokens[token_count][5]); |
684 | 699 | } |
685 | } else if (strncasecmp(line_tokens[token_count], "env_time", 8) == 0) { | |
700 | } else if (wm_strncasecmp(line_tokens[token_count], "env_time", 8) == 0) { | |
686 | 701 | if ((!wm_isdigit(line_tokens[token_count][8])) || |
687 | 702 | (!wm_isdigit(line_tokens[token_count][10])) || |
688 | 703 | (line_tokens[token_count][9] != '=')) { |
689 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in patch line)", 0); | |
704 | _WM_DEBUG_MSG("%s: syntax error in patch line for %s", config_file, "env_time"); | |
690 | 705 | } else { |
691 | 706 | uint32_t env_no = atoi(&line_tokens[token_count][8]); |
692 | 707 | if (env_no > 5) { |
693 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in patch line)", 0); | |
708 | _WM_DEBUG_MSG("%s: syntax error in patch line for %s", config_file, "env_time"); | |
694 | 709 | } else { |
695 | 710 | tmp_patch->env[env_no].time = (float) atof(&line_tokens[token_count][10]); |
696 | 711 | if ((tmp_patch->env[env_no].time > 45000.0f) || |
697 | 712 | (tmp_patch->env[env_no].time < 1.47f)) { |
698 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(range error in patch line)", 0); | |
713 | _WM_DEBUG_MSG("%s: range error in patch line %s", config_file, "env_time"); | |
699 | 714 | tmp_patch->env[env_no].set &= 0xFE; |
700 | 715 | } else { |
701 | 716 | tmp_patch->env[env_no].set |= 0x01; |
702 | 717 | } |
703 | 718 | } |
704 | 719 | } |
705 | } else if (strncasecmp(line_tokens[token_count], "env_level", 9) == 0) { | |
720 | } else if (wm_strncasecmp(line_tokens[token_count], "env_level", 9) == 0) { | |
706 | 721 | if ((!wm_isdigit(line_tokens[token_count][9])) || |
707 | 722 | (!wm_isdigit(line_tokens[token_count][11])) || |
708 | 723 | (line_tokens[token_count][10] != '=')) { |
709 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in patch line)", 0); | |
724 | _WM_DEBUG_MSG("%s: syntax error in patch line for %s", config_file, "env_level"); | |
710 | 725 | } else { |
711 | 726 | uint32_t env_no = atoi(&line_tokens[token_count][9]); |
712 | 727 | if (env_no > 5) { |
713 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(syntax error in patch line)", 0); | |
728 | _WM_DEBUG_MSG("%s: syntax error in patch line for %s", config_file, "env_level"); | |
714 | 729 | } else { |
715 | 730 | tmp_patch->env[env_no].level = (float) atof(&line_tokens[token_count][11]); |
716 | 731 | if ((tmp_patch->env[env_no].level > 1.0f) || |
717 | 732 | (tmp_patch->env[env_no].level < 0.0f)) { |
718 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(range error in patch line)", 0); | |
733 | _WM_DEBUG_MSG("%s: range error in patch line for %s", config_file, "env_level"); | |
719 | 734 | tmp_patch->env[env_no].set &= 0xFD; |
720 | 735 | } else { |
721 | 736 | tmp_patch->env[env_no].set |= 0x02; |
722 | 737 | } |
723 | 738 | } |
724 | 739 | } |
725 | } else if (strcasecmp(line_tokens[token_count], "keep=loop") == 0) { | |
740 | } else if (wm_strcasecmp(line_tokens[token_count], "keep=loop") == 0) { | |
726 | 741 | tmp_patch->keep |= SAMPLE_LOOP; |
727 | } else if (strcasecmp(line_tokens[token_count], "keep=env") == 0) { | |
742 | } else if (wm_strcasecmp(line_tokens[token_count], "keep=env") == 0) { | |
728 | 743 | tmp_patch->keep |= SAMPLE_ENVELOPE; |
729 | } else if (strcasecmp(line_tokens[token_count], "remove=sustain") == 0) { | |
744 | } else if (wm_strcasecmp(line_tokens[token_count], "remove=sustain") == 0) { | |
730 | 745 | tmp_patch->remove |= SAMPLE_SUSTAIN; |
731 | } else if (strcasecmp(line_tokens[token_count], "remove=clamped") == 0) { | |
746 | } else if (wm_strcasecmp(line_tokens[token_count], "remove=clamped") == 0) { | |
732 | 747 | tmp_patch->remove |= SAMPLE_CLAMPED; |
733 | 748 | } |
734 | 749 | token_count++; |
735 | 750 | } |
736 | 751 | } |
752 | } | |
753 | else if (_WM_Global_ErrorI) { /* malloc() failure in WM_LC_Tokenize_Line() */ | |
754 | WM_FreePatches(); | |
755 | free(line_tokens); | |
756 | free(config_buffer); | |
757 | return (-1); | |
737 | 758 | } |
738 | 759 | /* free up tokens */ |
739 | 760 | free(line_tokens); |
749 | 770 | return (0); |
750 | 771 | } |
751 | 772 | |
773 | static int WM_LoadConfig(const char *config_file) { | |
774 | return load_config(config_file, NULL); | |
775 | } | |
776 | ||
752 | 777 | static int add_handle(void * handle) { |
753 | 778 | struct _hndl *tmp_handle = NULL; |
754 | 779 | |
755 | 780 | if (first_handle == NULL) { |
756 | 781 | first_handle = malloc(sizeof(struct _hndl)); |
757 | 782 | if (first_handle == NULL) { |
758 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, " to get ram", errno); | |
783 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, " to get ram", errno); | |
759 | 784 | return (-1); |
760 | 785 | } |
761 | 786 | first_handle->handle = handle; |
769 | 794 | } |
770 | 795 | tmp_handle->next = malloc(sizeof(struct _hndl)); |
771 | 796 | if (tmp_handle->next == NULL) { |
772 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, " to get ram", errno); | |
797 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, " to get ram", errno); | |
773 | 798 | return (-1); |
774 | 799 | } |
775 | 800 | tmp_handle->next->prev = tmp_handle; |
1453 | 1478 | int ret; |
1454 | 1479 | |
1455 | 1480 | if (!file) { |
1456 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL filename)", 0); | |
1481 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL filename)", 0); | |
1457 | 1482 | return (-1); |
1458 | 1483 | } |
1459 | 1484 | if ((buf = (uint8_t *) _WM_BufferFile(file, size)) == NULL) { |
1468 | 1493 | WM_SYMBOL int WildMidi_ConvertBufferToMidi (uint8_t *in, uint32_t insize, |
1469 | 1494 | uint8_t **out, uint32_t *outsize) { |
1470 | 1495 | if (!in || !out || !outsize) { |
1471 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL params)", 0); | |
1496 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL params)", 0); | |
1472 | 1497 | return (-1); |
1473 | 1498 | } |
1474 | 1499 | |
1485 | 1510 | } |
1486 | 1511 | } |
1487 | 1512 | else if (!memcmp(in, "MThd", 4)) { |
1488 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, 0, "Already a midi file", 0); | |
1513 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, 0, "Already a midi file", 0); | |
1489 | 1514 | return (-1); |
1490 | 1515 | } |
1491 | 1516 | else { |
1492 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID, NULL, 0); | |
1517 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, NULL, 0); | |
1493 | 1518 | return (-1); |
1494 | 1519 | } |
1495 | 1520 | |
1511 | 1536 | |
1512 | 1537 | WM_SYMBOL int WildMidi_Init(const char *config_file, uint16_t rate, uint16_t mixer_options) { |
1513 | 1538 | if (WM_Initialized) { |
1514 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_ALR_INIT, NULL, 0); | |
1539 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_ALR_INIT, NULL, 0); | |
1515 | 1540 | return (-1); |
1516 | 1541 | } |
1517 | 1542 | |
1518 | 1543 | if (config_file == NULL) { |
1519 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, | |
1544 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, | |
1520 | 1545 | "(NULL config file pointer)", 0); |
1521 | 1546 | return (-1); |
1522 | 1547 | } |
1526 | 1551 | } |
1527 | 1552 | |
1528 | 1553 | if (mixer_options & 0x0FF0) { |
1529 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(invalid option)", | |
1554 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(invalid option)", | |
1530 | 1555 | 0); |
1531 | 1556 | WM_FreePatches(); |
1532 | 1557 | return (-1); |
1534 | 1559 | _WM_MixerOptions = mixer_options; |
1535 | 1560 | |
1536 | 1561 | if (rate < 11025) { |
1537 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, | |
1562 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, | |
1538 | 1563 | "(rate out of bounds, range is 11025 - 65535)", 0); |
1539 | 1564 | WM_FreePatches(); |
1540 | 1565 | return (-1); |
1551 | 1576 | |
1552 | 1577 | WM_SYMBOL int WildMidi_MasterVolume(uint8_t master_volume) { |
1553 | 1578 | if (!WM_Initialized) { |
1554 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1579 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1555 | 1580 | return (-1); |
1556 | 1581 | } |
1557 | 1582 | if (master_volume > 127) { |
1558 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, | |
1583 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, | |
1559 | 1584 | "(master volume out of range, range is 0-127)", 0); |
1560 | 1585 | return (-1); |
1561 | 1586 | } |
1570 | 1595 | struct _hndl * tmp_handle; |
1571 | 1596 | |
1572 | 1597 | if (!WM_Initialized) { |
1573 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1598 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1574 | 1599 | return (-1); |
1575 | 1600 | } |
1576 | 1601 | if (handle == NULL) { |
1577 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1602 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1578 | 1603 | return (-1); |
1579 | 1604 | } |
1580 | 1605 | if (first_handle == NULL) { |
1581 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(no midi's open)", 0); | |
1606 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(no midi's open)", 0); | |
1582 | 1607 | return (-1); |
1583 | 1608 | } |
1584 | 1609 | _WM_Lock(&mdi->lock); |
1618 | 1643 | midi * ret = NULL; |
1619 | 1644 | |
1620 | 1645 | if (!WM_Initialized) { |
1621 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1646 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1622 | 1647 | return (NULL); |
1623 | 1648 | } |
1624 | 1649 | if (midifile == NULL) { |
1625 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL filename)", 0); | |
1650 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL filename)", 0); | |
1626 | 1651 | return (NULL); |
1627 | 1652 | } |
1628 | 1653 | |
1658 | 1683 | midi * ret = NULL; |
1659 | 1684 | |
1660 | 1685 | if (!WM_Initialized) { |
1661 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1686 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1662 | 1687 | return (NULL); |
1663 | 1688 | } |
1664 | 1689 | if (midibuffer == NULL) { |
1665 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL midi data buffer)", 0); | |
1690 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL midi data buffer)", 0); | |
1666 | 1691 | return (NULL); |
1667 | 1692 | } |
1668 | 1693 | if (size > WM_MAXFILESIZE) { |
1669 | 1694 | /* don't bother loading suspiciously long files */ |
1670 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_LONGFIL, NULL, 0); | |
1695 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_LONGFIL, NULL, 0); | |
1671 | 1696 | return (NULL); |
1672 | 1697 | } |
1673 | 1698 | if (memcmp(midibuffer,"HMIMIDIP", 8) == 0) { |
1698 | 1723 | struct _note *note_data; |
1699 | 1724 | |
1700 | 1725 | if (!WM_Initialized) { |
1701 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1726 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1702 | 1727 | return (-1); |
1703 | 1728 | } |
1704 | 1729 | if (handle == NULL) { |
1705 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1730 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1706 | 1731 | return (-1); |
1707 | 1732 | } |
1708 | 1733 | if (sample_pos == NULL) { |
1709 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL seek position pointer)", 0); | |
1734 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL seek position pointer)", 0); | |
1710 | 1735 | return (-1); |
1711 | 1736 | } |
1712 | 1737 | |
1791 | 1816 | struct _note *note_data; |
1792 | 1817 | |
1793 | 1818 | if (!WM_Initialized) { |
1794 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1819 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1795 | 1820 | return (-1); |
1796 | 1821 | } |
1797 | 1822 | if (handle == NULL) { |
1798 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1823 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1799 | 1824 | return (-1); |
1800 | 1825 | } |
1801 | 1826 | mdi = (struct _mdi *) handle; |
1802 | 1827 | _WM_Lock(&mdi->lock); |
1803 | 1828 | |
1804 | 1829 | if ((!mdi->is_type2) && (nextsong != 0)) { |
1805 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(Illegal use. Only usable with files detected to be type 2 compatable.", 0); | |
1830 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(Illegal use. Only usable with files detected to be type 2 compatible.", 0); | |
1806 | 1831 | _WM_Unlock(&mdi->lock); |
1807 | 1832 | return (-1); |
1808 | 1833 | } |
1809 | 1834 | if ((nextsong > 1) || (nextsong < -1)) { |
1810 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(Invalid nextsong setting. -1 is previous song, 0 start of current song, 1 is next song)", 0); | |
1835 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(Invalid nextsong setting. -1 is previous song, 0 start of current song, 1 is next song)", 0); | |
1811 | 1836 | _WM_Unlock(&mdi->lock); |
1812 | 1837 | return (-1); |
1813 | 1838 | } |
1895 | 1920 | |
1896 | 1921 | WM_SYMBOL int WildMidi_GetOutput(midi * handle, int8_t *buffer, uint32_t size) { |
1897 | 1922 | if (__builtin_expect((!WM_Initialized), 0)) { |
1898 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1923 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1899 | 1924 | return (-1); |
1900 | 1925 | } |
1901 | 1926 | if (__builtin_expect((handle == NULL), 0)) { |
1902 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1927 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1903 | 1928 | return (-1); |
1904 | 1929 | } |
1905 | 1930 | if (__builtin_expect((buffer == NULL), 0)) { |
1906 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL buffer pointer)", 0); | |
1931 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL buffer pointer)", 0); | |
1907 | 1932 | return (-1); |
1908 | 1933 | } |
1909 | 1934 | if (__builtin_expect((size == 0), 0)) { |
1910 | 1935 | return (0); |
1911 | 1936 | } |
1912 | 1937 | if (__builtin_expect((!!(size % 4)), 0)) { |
1913 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(size not a multiple of 4)", 0); | |
1938 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(size not a multiple of 4)", 0); | |
1914 | 1939 | return (-1); |
1915 | 1940 | } |
1916 | 1941 | |
1923 | 1948 | |
1924 | 1949 | WM_SYMBOL int WildMidi_GetMidiOutput(midi * handle, int8_t **buffer, uint32_t *size) { |
1925 | 1950 | if (__builtin_expect((!WM_Initialized), 0)) { |
1926 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1951 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1927 | 1952 | return (-1); |
1928 | 1953 | } |
1929 | 1954 | if (__builtin_expect((handle == NULL), 0)) { |
1930 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1955 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1931 | 1956 | return (-1); |
1932 | 1957 | } |
1933 | 1958 | if (__builtin_expect((buffer == NULL), 0)) { |
1934 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL buffer pointer)", 0); | |
1935 | return (-1); | |
1936 | } | |
1937 | _WM_Event2Midi(handle, (uint8_t **)buffer, size); | |
1938 | return 0; | |
1959 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL buffer pointer)", 0); | |
1960 | return (-1); | |
1961 | } | |
1962 | return _WM_Event2Midi(handle, (uint8_t **)buffer, size); | |
1939 | 1963 | } |
1940 | 1964 | |
1941 | 1965 | |
1943 | 1967 | struct _mdi *mdi; |
1944 | 1968 | |
1945 | 1969 | if (!WM_Initialized) { |
1946 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1970 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
1947 | 1971 | return (-1); |
1948 | 1972 | } |
1949 | 1973 | if (handle == NULL) { |
1950 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1974 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
1951 | 1975 | return (-1); |
1952 | 1976 | } |
1953 | 1977 | |
1954 | 1978 | mdi = (struct _mdi *) handle; |
1955 | 1979 | _WM_Lock(&mdi->lock); |
1956 | 1980 | if ((!(options & 0x800F)) || (options & 0x7FF0)) { |
1957 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(invalid option)", 0); | |
1981 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(invalid option)", 0); | |
1958 | 1982 | _WM_Unlock(&mdi->lock); |
1959 | 1983 | return (-1); |
1960 | 1984 | } |
1961 | 1985 | if (setting & 0x7FF0) { |
1962 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(invalid setting)", 0); | |
1986 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(invalid setting)", 0); | |
1963 | 1987 | _WM_Unlock(&mdi->lock); |
1964 | 1988 | return (-1); |
1965 | 1989 | } |
1988 | 2012 | WM_ConvertOptions.frequency = setting; |
1989 | 2013 | break; |
1990 | 2014 | default: |
1991 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(invalid setting)", 0); | |
2015 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(invalid setting)", 0); | |
1992 | 2016 | _WM_Unlock(&WM_ConvertOptions.lock); |
1993 | 2017 | return (-1); |
1994 | 2018 | } |
2000 | 2024 | WildMidi_GetInfo(midi * handle) { |
2001 | 2025 | struct _mdi *mdi = (struct _mdi *) handle; |
2002 | 2026 | if (!WM_Initialized) { |
2003 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
2027 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
2004 | 2028 | return (NULL); |
2005 | 2029 | } |
2006 | 2030 | if (handle == NULL) { |
2007 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
2031 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
2008 | 2032 | return (NULL); |
2009 | 2033 | } |
2010 | 2034 | _WM_Lock(&mdi->lock); |
2011 | 2035 | if (mdi->tmp_info == NULL) { |
2012 | 2036 | mdi->tmp_info = malloc(sizeof(struct _WM_Info)); |
2013 | 2037 | if (mdi->tmp_info == NULL) { |
2014 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to set info", 0); | |
2038 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to set info", 0); | |
2015 | 2039 | _WM_Unlock(&mdi->lock); |
2016 | 2040 | return (NULL); |
2017 | 2041 | } |
2025 | 2049 | free(mdi->tmp_info->copyright); |
2026 | 2050 | mdi->tmp_info->copyright = malloc(strlen(mdi->extra_info.copyright) + 1); |
2027 | 2051 | if (mdi->tmp_info->copyright == NULL) { |
2028 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_MEM, "to set copyright", 0); | |
2052 | free(mdi->tmp_info); | |
2053 | mdi->tmp_info = NULL; | |
2054 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to set copyright", 0); | |
2055 | _WM_Unlock(&mdi->lock); | |
2056 | return (NULL); | |
2029 | 2057 | } else { |
2030 | 2058 | strcpy(mdi->tmp_info->copyright, mdi->extra_info.copyright); |
2031 | 2059 | } |
2038 | 2066 | |
2039 | 2067 | WM_SYMBOL int WildMidi_Shutdown(void) { |
2040 | 2068 | if (!WM_Initialized) { |
2041 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
2069 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
2042 | 2070 | return (-1); |
2043 | 2071 | } |
2044 | 2072 | while (first_handle) { |
2089 | 2117 | char * lyric = NULL; |
2090 | 2118 | |
2091 | 2119 | if (!WM_Initialized) { |
2092 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
2120 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); | |
2093 | 2121 | return (NULL); |
2094 | 2122 | } |
2095 | 2123 | if (handle == NULL) { |
2096 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
2124 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", 0); | |
2097 | 2125 | return (NULL); |
2098 | 2126 | } |
2099 | 2127 | _WM_Lock(&mdi->lock); |
2114 | 2142 | * Clear any error message |
2115 | 2143 | */ |
2116 | 2144 | WM_SYMBOL void WildMidi_ClearError (void) { |
2145 | _WM_Global_ErrorI = 0; | |
2117 | 2146 | if (_WM_Global_ErrorS != NULL) { |
2118 | 2147 | free(_WM_Global_ErrorS); |
2119 | 2148 | _WM_Global_ErrorS = NULL; |
28 | 28 | #include <stdlib.h> |
29 | 29 | #include "wm_error.h" |
30 | 30 | |
31 | void _WM_ERROR_NEW(const char * wmfmt, ...) { | |
31 | void _WM_DEBUG_MSG(const char * wmfmt, ...) { | |
32 | 32 | va_list args; |
33 | 33 | fprintf(stderr, "\r"); |
34 | 34 | va_start(args, wmfmt); |
38 | 38 | } |
39 | 39 | |
40 | 40 | static const char *errors[WM_ERR_MAX+1] = { |
41 | "System Error", | |
41 | "No Error", | |
42 | 42 | |
43 | 43 | "Unable to obtain memory", |
44 | 44 | "Unable to stat", |
45 | 45 | "Unable to load", |
46 | 46 | "Unable to open", |
47 | 47 | "Unable to read", |
48 | "Invalid or Unsuported file format", | |
48 | "Invalid or Unsupported file format", | |
49 | 49 | "File corrupt", |
50 | 50 | "Library not Initialized", |
51 | 51 | "Invalid argument", |
66 | 66 | char * _WM_Global_ErrorS = NULL; |
67 | 67 | int _WM_Global_ErrorI = 0; |
68 | 68 | |
69 | void _WM_GLOBAL_ERROR(const char * func, const char * file, unsigned int lne, int wmerno, const char * wmfor, int error) { | |
69 | void _WM_GLOBAL_ERROR(const char *func, int lne, int wmerno, const char *wmfor, int error) { | |
70 | 70 | |
71 | char * errorstring = NULL; | |
71 | char *errorstring; | |
72 | 72 | |
73 | if ((wmerno < 0) || (wmerno >= WM_ERR_MAX)) return; | |
73 | if (wmerno < 0 || wmerno >= WM_ERR_MAX) | |
74 | wmerno = WM_ERR_MAX; /* set to invalid error code. */ | |
74 | 75 | |
75 | 76 | _WM_Global_ErrorI = wmerno; |
76 | 77 | |
77 | 78 | if (_WM_Global_ErrorS != NULL) free(_WM_Global_ErrorS); |
78 | 79 | |
79 | errorstring = calloc(1, MAX_ERROR_LEN+1); | |
80 | errorstring = malloc(MAX_ERROR_LEN+1); | |
80 | 81 | |
81 | 82 | if (error == 0) { |
82 | 83 | if (wmfor == NULL) { |
83 | sprintf(errorstring,"Error (%s:%s:%i) %s", | |
84 | func, file, lne, errors[wmerno]); | |
84 | sprintf(errorstring,"Error (%s:%i) %s", | |
85 | func, lne, errors[wmerno]); | |
85 | 86 | } else { |
86 | sprintf(errorstring,"Error (%s:%s:%i) %s (%s)", | |
87 | func, file, lne, wmfor, errors[wmerno]); | |
87 | sprintf(errorstring,"Error (%s:%i) %s (%s)", | |
88 | func, lne, wmfor, errors[wmerno]); | |
88 | 89 | } |
89 | 90 | } else { |
90 | 91 | if (wmfor == NULL) { |
91 | sprintf(errorstring,"System Error (%s:%s:%i) %s : %s", | |
92 | func, file, lne, errors[wmerno], strerror(error)); | |
92 | sprintf(errorstring,"System Error (%s:%i) %s : %s", | |
93 | func, lne, errors[wmerno], strerror(error)); | |
93 | 94 | } else { |
94 | sprintf(errorstring,"System Error (%s:%s:%i) %s (%s) : %s", | |
95 | func, file, lne, wmfor, errors[wmerno], strerror(error)); | |
95 | sprintf(errorstring,"System Error (%s:%i) %s (%s) : %s", | |
96 | func, lne, wmfor, errors[wmerno], strerror(error)); | |
96 | 97 | } |
97 | 98 | } |
98 | 99 | |
100 | errorstring[MAX_ERROR_LEN] = 0; | |
99 | 101 | _WM_Global_ErrorS = errorstring; |
100 | ||
101 | return; | |
102 | 102 | } |
103 | 103 | |
104 | void _WM_ERROR(const char * func, unsigned int lne, int wmerno, | |
105 | const char * wmfor, int error) { | |
106 | ||
107 | static const char *errors[WM_ERR_MAX+1] = { | |
108 | "No error", | |
109 | ||
110 | "Unable to obtain memory", | |
111 | "Unable to stat", | |
112 | "Unable to load", | |
113 | "Unable to open", | |
114 | "Unable to read", | |
115 | "Invalid or Unsuported file format", | |
116 | "File corrupt", | |
117 | "Library not Initialized", | |
118 | "Invalid argument", | |
119 | "Library Already Initialized", | |
120 | "Not a midi file", | |
121 | "Refusing to load unusually long file", | |
122 | "Not an hmp file", | |
123 | "Not an hmi file", | |
124 | "Unable to convert", | |
125 | "Not a mus file", | |
126 | "Not an xmi file", | |
127 | ||
128 | "Invalid error code" | |
129 | }; | |
130 | ||
131 | if (wmerno < 0 || wmerno > WM_ERR_MAX) | |
132 | wmerno = WM_ERR_MAX; | |
133 | ||
134 | if (wmfor != NULL) { | |
135 | if (error != 0) { | |
136 | fprintf(stderr, "\rlibWildMidi(%s:%u): ERROR %s %s (%s)\n", func, | |
137 | lne, errors[wmerno], wmfor, strerror(error)); | |
138 | } else { | |
139 | fprintf(stderr, "\rlibWildMidi(%s:%u): ERROR %s %s\n", func, lne, | |
140 | errors[wmerno], wmfor); | |
141 | } | |
142 | } else { | |
143 | if (error != 0) { | |
144 | fprintf(stderr, "\rlibWildMidi(%s:%u): ERROR %s (%s)\n", func, lne, | |
145 | errors[wmerno], strerror(error)); | |
146 | } else { | |
147 | fprintf(stderr, "\rlibWildMidi(%s:%u): ERROR %s\n", func, lne, | |
148 | errors[wmerno]); | |
149 | } | |
150 | } | |
104 | void _WM_ERROR_NEW(const char * wmfmt, ...) { | |
105 | char *errorstring; | |
106 | va_list args; | |
107 | va_start(args, wmfmt); | |
108 | errorstring = malloc(MAX_ERROR_LEN+1); | |
109 | vsprintf(errorstring, wmfmt, args); | |
110 | va_end(args); | |
111 | errorstring[MAX_ERROR_LEN] = 0; | |
112 | _WM_Global_ErrorS = errorstring; | |
113 | _WM_Global_ErrorI = WM_ERR_MAX;/* well, it's a custom error message */ | |
151 | 114 | } |
23 | 23 | |
24 | 24 | #include "config.h" |
25 | 25 | |
26 | #if !defined(_WIN32) && !defined(__DJGPP__) | |
26 | #if !(defined(_WIN32) || defined(__DJGPP__) || defined(WILDMIDI_AMIGA) || defined(__OS2__) || defined(__EMX__)) | |
27 | 27 | |
28 | 28 | #define _XOPEN_SOURCE 600 /* for ONLCR */ |
29 | 29 | |
65 | 65 | _tty.c_lflag = _res_lflg; |
66 | 66 | tcsetattr(STDIN_FILENO, TCSADRAIN, &_tty); |
67 | 67 | } |
68 | #endif /* !_WIN32, !__DJGPP__ */ | |
68 | #endif /* !(_WIN32,__DJGPP__,__OS2__) */ |
57 | 57 | } midi_descriptor; |
58 | 58 | |
59 | 59 | struct xmi_ctx { |
60 | uint8_t *src, *src_ptr; | |
60 | const uint8_t *src, *src_ptr; | |
61 | 61 | uint32_t srcsize; |
62 | 62 | uint32_t datastart; |
63 | 63 | uint8_t *dst, *dst_ptr; |
460 | 460 | 121, 0 /* 127 Jungle Tune set to Breath Noise */ |
461 | 461 | }; |
462 | 462 | |
463 | int _WM_xmi2midi(uint8_t *in, uint32_t insize, | |
463 | int _WM_xmi2midi(const uint8_t *in, uint32_t insize, | |
464 | 464 | uint8_t **out, uint32_t *outsize, |
465 | 465 | uint32_t convert_type) { |
466 | 466 | struct xmi_ctx ctx; |
478 | 478 | ctx.convert_type = convert_type; |
479 | 479 | |
480 | 480 | if (ParseXMI(&ctx) < 0) { |
481 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
481 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_XMI, NULL, 0); | |
482 | 482 | goto _end; |
483 | 483 | } |
484 | 484 | |
485 | 485 | if (ExtractTracks(&ctx) < 0) { |
486 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_NOT_MIDI, NULL, 0); | |
486 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_MIDI, NULL, 0); | |
487 | 487 | goto _end; |
488 | 488 | } |
489 | 489 | |
909 | 909 | |
910 | 910 | /* Never occur */ |
911 | 911 | default: |
912 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(unrecognized event)", 0); | |
912 | _WM_DEBUG_MSG("%s: unrecognized event", __FUNCTION__); | |
913 | 913 | break; |
914 | 914 | } |
915 | 915 | } |
952 | 952 | |
953 | 953 | /* Convert it */ |
954 | 954 | if (!(ppqn = ConvertFiletoList(ctx))) { |
955 | _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, NULL, 0); | |
955 | _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); | |
956 | 956 | break; |
957 | 957 | } |
958 | 958 | ctx->timing[num] = ppqn; |
979 | 979 | |
980 | 980 | file_size = getsrcsize(ctx); |
981 | 981 | if (getsrcpos(ctx) + 8 > file_size) { |
982 | badfile: _WM_GLOBAL_ERROR(__FUNCTION__, __FILE__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
982 | badfile: _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); | |
983 | 983 | return (-1); |
984 | 984 | } |
985 | 985 | |
1000 | 1000 | |
1001 | 1001 | /* XDIRless XMIDI, we can handle them here. */ |
1002 | 1002 | if (!memcmp(buf, "XMID", 4)) { |
1003 | _WM_ERROR_NEW("Warning: XMIDI without XDIR"); | |
1003 | _WM_DEBUG_MSG("Warning: XMIDI without XDIR"); | |
1004 | 1004 | ctx->info.tracks = 1; |
1005 | 1005 | } |
1006 | 1006 | /* Not an XMIDI that we recognise */ |