void Picture_writeToWindowsMetafile (Picture me, MelderFile file) { try { HENHMETAFILE metafile = copyToMetafile (me); MelderFile_delete (file); // overwrite any existing file with the same name DeleteEnhMetaFile (CopyEnhMetaFile (metafile, Melder_peek32toW (file -> path))); DeleteEnhMetaFile (metafile); } catch (MelderError) { Melder_throw (U"Picture not written to Windows metafile ", file); } }
void Melder_system (const char32 *command) { if (! command) command = U""; #if defined (macintosh) || defined (UNIX) if (system (Melder_peek32to8 (command)) != 0) Melder_throw (U"System command failed."); #elif defined (_WIN32) STARTUPINFO siStartInfo; PROCESS_INFORMATION piProcInfo; char32 *comspec = Melder_getenv (U"COMSPEC"); // e.g. "C:\WINDOWS\COMMAND.COM" or "C:\WINNT\windows32\cmd.exe" if (! comspec) { comspec = Melder_getenv (U"ComSpec"); } autoMelderString buffer; if (comspec) { MelderString_copy (& buffer, comspec); } else { OSVERSIONINFOEX osVersionInfo; memset (& osVersionInfo, 0, sizeof (OSVERSIONINFOEX)); osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo)) { osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo)) Melder_throw (U"System command cannot find system version."); } switch (osVersionInfo. dwPlatformId) { case VER_PLATFORM_WIN32_NT: { MelderString_copy (& buffer, U"cmd.exe"); } break; case VER_PLATFORM_WIN32_WINDOWS: { MelderString_copy (& buffer, U"command.com"); } break; default: { MelderString_copy (& buffer, U"command.com"); } } } MelderString_append (& buffer, U" /c ", command); memset (& siStartInfo, 0, sizeof (siStartInfo)); siStartInfo. cb = sizeof (siStartInfo); if (! CreateProcess (nullptr, Melder_peek32toW (buffer.string), nullptr, nullptr, true, CREATE_NO_WINDOW, nullptr, nullptr, & siStartInfo, & piProcInfo)) Melder_throw (U"Cannot create subprocess."); WaitForSingleObject (piProcInfo. hProcess, -1); CloseHandle (piProcInfo. hProcess); CloseHandle (piProcInfo. hThread); #endif }
/* BSD systems provide ftruncate, several others supply chsize, and a few may provide a (possibly undocumented) fcntl option F_FREESP. Under MS-DOS, you can sometimes use write(fd, "", 0). However, there is no portable solution, nor a way to delete blocks at the beginning. */ static void MelderFile_truncate (MelderFile me, long size) { #if defined(_WIN32) HANDLE hFile; DWORD fdwAccess = GENERIC_READ | GENERIC_WRITE, fPos; DWORD fdwShareMode = 0; /* File cannot be shared */ LPSECURITY_ATTRIBUTES lpsa = nullptr; DWORD fdwCreate = OPEN_EXISTING; LARGE_INTEGER fileSize; MelderFile_close (me); hFile = CreateFileW (Melder_peek32toW (my path), fdwAccess, fdwShareMode, lpsa, fdwCreate, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { Melder_throw (U"Can't open file ", me, U"."); } // Set current file pointer to position 'size' fileSize.LowPart = size; fileSize.HighPart = 0; /* Limit the file size to 2^32 - 2 bytes */ fPos = SetFilePointer (hFile, fileSize.LowPart, &fileSize.HighPart, FILE_BEGIN); if (fPos == 0xFFFFFFFF) { Melder_throw (U"Can't set the position at size ", size, U"for file ", me, U"."); } // Limit the file size as the current position of the file pointer. SetEndOfFile (hFile); CloseHandle (hFile); #elif defined(linux) || defined(macintosh) MelderFile_close (me); if (truncate (Melder_peek32to8 (my path), size) == -1) Melder_throw (U"Truncating failed for file ", MelderFile_messageName (me), U" (", Melder_peek8to32 (strerror (errno)), U")."); #else Melder_throw (U"Don't know what to do."); #endif }
static void NativeMenuItem_setText (GuiObject me) { int acc = my motiff.pushButton.acceleratorChar, modifiers = my motiff.pushButton.acceleratorModifiers; static MelderString title { 0 }; if (acc == 0) { MelderString_copy (& title, _GuiWin_expandAmpersands (my name)); } else { static const char32 *keyStrings [256] = { 0, U"<-", U"->", U"Up", U"Down", U"PAUSE", U"Del", U"Ins", U"Backspace", U"Tab", U"LineFeed", U"Home", U"End", U"Enter", U"PageUp", U"PageDown", U"Esc", U"F1", U"F2", U"F3", U"F4", U"F5", U"F6", U"F7", U"F8", U"F9", U"F10", U"F11", U"F12", 0, 0, 0, U"Space", U"!", U"\"", U"#", U"$", U"%", U"&", U"\'", U"(", U")", U"*", U"+", U",", U"-", U".", U"/", U"0", U"1", U"2", U"3", U"4", U"5", U"6", U"7", U"8", U"9", U":", U";", U"<", U"=", U">", U"?", U"@", U"A", U"B", U"C", U"D", U"E", U"F", U"G", U"H", U"I", U"J", U"K", U"L", U"M", U"N", U"O", U"P", U"Q", U"R", U"S", U"T", U"U", U"V", U"W", U"X", U"Y", U"Z", U"[", U"\\", U"]", U"^", U"_", U"`", U"a", U"b", U"c", U"d", U"e", U"f", U"g", U"h", U"i", U"j", U"k", U"l", U"m", U"n", U"o", U"p", U"q", U"r", U"s", U"t", U"u", U"v", U"w", U"x", U"y", U"z", U"{", U"|", U"}", U"~", U"Del", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"[", U"]", U",", U"?", U".", U"\\", U";", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"-", U"`", U"=", U"\'", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const char32 *keyString = keyStrings [acc] ? keyStrings [acc] : U"???"; MelderString_copy (& title, _GuiWin_expandAmpersands (my name), U"\t", modifiers & _motif_COMMAND_MASK ? U"Ctrl-" : nullptr, modifiers & _motif_OPTION_MASK ? U"Alt-" : nullptr, modifiers & _motif_SHIFT_MASK ? U"Shift-" : nullptr, keyString); } ModifyMenu (my nat.entry.handle, my nat.entry.id, MF_BYCOMMAND | MF_STRING, my nat.entry.id, Melder_peek32toW (title.string)); }
autoSound SpeechSynthesizer_to_Sound (SpeechSynthesizer me, const char32 *text, autoTextGrid *tg, autoTable *events) { try { int fsamp = espeak_Initialize (AUDIO_OUTPUT_SYNCHRONOUS, 0, nullptr, // 5000ms espeakINITIALIZE_PHONEME_EVENTS|espeakINITIALIZE_PHONEME_IPA); if (fsamp == -1) { Melder_throw (U"Internal espeak error."); } int synth_flags = espeakCHARS_WCHAR; if (my d_inputTextFormat == SpeechSynthesizer_INPUT_TAGGEDTEXT) { synth_flags |= espeakSSML; } if (my d_inputTextFormat != SpeechSynthesizer_INPUT_TEXTONLY) { synth_flags |= espeakPHONEMES; } option_phoneme_events = espeakINITIALIZE_PHONEME_EVENTS; // extern int option_phoneme_events; if (my d_outputPhonemeCoding == SpeechSynthesizer_PHONEMECODINGS_IPA) { option_phoneme_events |= espeakINITIALIZE_PHONEME_IPA; } espeak_SetParameter (espeakRATE, my d_wordsPerMinute, 0); espeak_SetParameter (espeakPITCH, my d_pitchAdjustment, 0); espeak_SetParameter (espeakRANGE, my d_pitchRange, 0); const char32 *voiceLanguageCode = SpeechSynthesizer_getVoiceLanguageCodeFromName (me, my d_voiceLanguageName); const char32 *voiceVariantCode = SpeechSynthesizer_getVoiceVariantCodeFromName (me, my d_voiceVariantName); espeakdata_SetVoiceByName ((const char *) Melder_peek32to8 (voiceLanguageCode), (const char *) Melder_peek32to8 (voiceVariantCode)); espeak_SetParameter (espeakWORDGAP, my d_wordgap * 100, 0); // espeak wordgap is in units of 10 ms espeak_SetParameter (espeakCAPITALS, 0, 0); espeak_SetParameter (espeakPUNCTUATION, espeakPUNCT_NONE, 0); espeak_SetSynthCallback (synthCallback); my d_events = Table_createWithColumnNames (0, U"time type type-t t-pos length a-pos sample id uniq"); #ifdef _WIN32 wchar_t *textW = Melder_peek32toW (text); espeak_Synth (textW, wcslen (textW) + 1, 0, POS_CHARACTER, 0, synth_flags, nullptr, me); #else espeak_Synth (text, str32len (text) + 1, 0, POS_CHARACTER, 0, synth_flags, nullptr, me); #endif espeak_Terminate (); autoSound thee = buffer_to_Sound (my d_wav, my d_numberOfSamples, my d_internalSamplingFrequency); if (my d_samplingFrequency != my d_internalSamplingFrequency) { thee = Sound_resample (thee.get(), my d_samplingFrequency, 50); } my d_numberOfSamples = 0; // re-use the wav-buffer if (tg) { double xmin = Table_getNumericValue_Assert (my d_events.get(), 1, 1); if (xmin > thy xmin) { xmin = thy xmin; } double xmax = Table_getNumericValue_Assert (my d_events.get(), my d_events -> rows.size, 1); if (xmax < thy xmax) { xmax = thy xmax; } autoTextGrid tg1 = Table_to_TextGrid (my d_events.get(), text, xmin, xmax); *tg = TextGrid_extractPart (tg1.get(), thy xmin, thy xmax, 0); } if (events) { Table_setEventTypeString (my d_events.get()); *events = my d_events.move(); } my d_events.reset(); return thee; } catch (MelderError) { espeak_Terminate (); Melder_throw (U"Text not played."); } }
static void NativeMenuItem_setText (GuiObject me) { int acc = my motiff.pushButton.acceleratorChar, modifiers = my motiff.pushButton.acceleratorModifiers; #if win static MelderString title { 0 }; if (acc == 0) { MelderString_copy (& title, _GuiWin_expandAmpersands (my name)); } else { static const char32 *keyStrings [256] = { 0, U"<-", U"->", U"Up", U"Down", U"PAUSE", U"Del", U"Ins", U"Backspace", U"Tab", U"LineFeed", U"Home", U"End", U"Enter", U"PageUp", U"PageDown", U"Esc", U"F1", U"F2", U"F3", U"F4", U"F5", U"F6", U"F7", U"F8", U"F9", U"F10", U"F11", U"F12", 0, 0, 0, U"Space", U"!", U"\"", U"#", U"$", U"%", U"&", U"\'", U"(", U")", U"*", U"+", U",", U"-", U".", U"/", U"0", U"1", U"2", U"3", U"4", U"5", U"6", U"7", U"8", U"9", U":", U";", U"<", U"=", U">", U"?", U"@", U"A", U"B", U"C", U"D", U"E", U"F", U"G", U"H", U"I", U"J", U"K", U"L", U"M", U"N", U"O", U"P", U"Q", U"R", U"S", U"T", U"U", U"V", U"W", U"X", U"Y", U"Z", U"[", U"\\", U"]", U"^", U"_", U"`", U"a", U"b", U"c", U"d", U"e", U"f", U"g", U"h", U"i", U"j", U"k", U"l", U"m", U"n", U"o", U"p", U"q", U"r", U"s", U"t", U"u", U"v", U"w", U"x", U"y", U"z", U"{", U"|", U"}", U"~", U"Del", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"[", U"]", U",", U"?", U".", U"\\", U";", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"-", U"`", U"=", U"\'", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const char32 *keyString = keyStrings [acc] ? keyStrings [acc] : U"???"; MelderString_copy (& title, _GuiWin_expandAmpersands (my name), U"\t", modifiers & _motif_COMMAND_MASK ? U"Ctrl-" : nullptr, modifiers & _motif_OPTION_MASK ? U"Alt-" : nullptr, modifiers & _motif_SHIFT_MASK ? U"Shift-" : nullptr, keyString); } ModifyMenu (my nat.entry.handle, my nat.entry.id, MF_BYCOMMAND | MF_STRING, my nat.entry.id, Melder_peek32toW (title.string)); #elif mac static int theGlyphs [1+31] = { 0, kMenuLeftArrowDashedGlyph, kMenuRightArrowDashedGlyph, kMenuUpArrowDashedGlyph, kMenuDownwardArrowDashedGlyph, 0, kMenuDeleteRightGlyph, 0, kMenuDeleteLeftGlyph, kMenuTabRightGlyph, 0, 0, 0, kMenuReturnGlyph, kMenuPageUpGlyph, kMenuPageDownGlyph, kMenuEscapeGlyph, kMenuF1Glyph, kMenuF2Glyph, kMenuF3Glyph, kMenuF4Glyph, kMenuF5Glyph, kMenuF6Glyph, kMenuF7Glyph, kMenuF8Glyph, kMenuF9Glyph, kMenuF10Glyph, kMenuF11Glyph, kMenuF12Glyph, 0, 0, 0 }; SetMenuItemTextWithCFString (my nat.entry.handle, my nat.entry.item, (CFStringRef) Melder_peek32toCfstring (my name)); if (acc > 32) { SetItemCmd (my nat.entry.handle, my nat.entry.item, acc); } else { Melder_assert (acc > 0 && acc < 32); SetItemCmd (my nat.entry.handle, my nat.entry.item, ' '); /* Funny that this should be needed. */ SetMenuItemKeyGlyph (my nat.entry.handle, my nat.entry.item, theGlyphs [acc]); } SetMenuItemModifiers (my nat.entry.handle, my nat.entry.item, ( modifiers & _motif_OPTION_MASK ? kMenuOptionModifier : 0 ) + ( modifiers & _motif_SHIFT_MASK ? kMenuShiftModifier : 0 ) + ( modifiers & _motif_COMMAND_MASK ? 0 : kMenuNoCommandModifier )); #endif }
static autoStrings Strings_createAsFileOrDirectoryList (const char32 *path /* cattable */, int type) { #if USE_STAT /* * Initialize. */ DIR *d = nullptr; try { autoMelderString filePath, searchDirectory, left, right; /* * Parse the path. * Example: in /Users/paul/sounds/h*.wav", * the search directory is "/Users/paul/sounds", * the left environment is "h", and the right environment is ".wav". */ MelderString_copy (& searchDirectory, path); char32 *asterisk = str32rchr (searchDirectory. string, '*'); if (asterisk) { *asterisk = '\0'; searchDirectory. length = asterisk - searchDirectory. string; // probably superfluous, but correct char32 *lastSlash = str32rchr (searchDirectory. string, Melder_DIRECTORY_SEPARATOR); if (lastSlash) { *lastSlash = '\0'; // This fixes searchDirectory. searchDirectory. length = lastSlash - searchDirectory. string; // probably superfluous, but correct MelderString_copy (& left, lastSlash + 1); } else { MelderString_copy (& left, searchDirectory. string); // quickly save... MelderString_empty (& searchDirectory); // ...before destruction } MelderString_copy (& right, asterisk + 1); } char buffer8 [kMelder_MAXPATH+1]; Melder_str32To8bitFileRepresentation_inline (searchDirectory. string, buffer8); d = opendir (buffer8 [0] ? buffer8 : "."); if (! d) Melder_throw (U"Cannot open directory ", searchDirectory. string, U"."); //Melder_casual (U"opened"); autoStrings me = Thing_new (Strings); my strings = NUMvector <char32 *> (1, 1000000); struct dirent *entry; while (!! (entry = readdir (d))) { MelderString_copy (& filePath, searchDirectory. string [0] ? searchDirectory. string : U"."); MelderString_appendCharacter (& filePath, Melder_DIRECTORY_SEPARATOR); char32 buffer32 [kMelder_MAXPATH+1]; Melder_8bitFileRepresentationToStr32_inline (entry -> d_name, buffer32); MelderString_append (& filePath, buffer32); //Melder_casual (U"read ", filePath. string); Melder_str32To8bitFileRepresentation_inline (filePath. string, buffer8); struct stat stats; if (stat (buffer8, & stats) != 0) { //Melder_throw (U"Cannot look at file ", filePath. string, U"."); //stats. st_mode = -1L; } //Melder_casual (U"statted ", filePath. string); //Melder_casual (U"file ", filePath. string, U" mode ", stats. st_mode / 4096); if ((type == Strings_createAsFileOrDirectoryList_TYPE_FILE && S_ISREG (stats. st_mode)) || (type == Strings_createAsFileOrDirectoryList_TYPE_DIRECTORY && S_ISDIR (stats. st_mode))) { Melder_8bitFileRepresentationToStr32_inline (entry -> d_name, buffer32); int64 length = str32len (buffer32); if (buffer32 [0] != U'.' && (left. length == 0 || str32nequ (buffer32, left. string, left. length)) && (right. length == 0 || (length >= right. length && str32equ (buffer32 + (length - right. length), right. string)))) { my strings [++ my numberOfStrings] = Melder_dup (buffer32); } } } closedir (d); Strings_sort (me.get()); return me; } catch (MelderError) { if (d) closedir (d); // "finally" throw; } #elif defined (_WIN32) try { char32 searchPath [kMelder_MAXPATH+1]; int len = str32len (path); bool hasAsterisk = !! str32chr (path, U'*'); bool endsInSeparator = ( len != 0 && path [len - 1] == U'\\' ); autoStrings me = Thing_new (Strings); my strings = NUMvector <char32 *> (1, 1000000); Melder_sprint (searchPath, kMelder_MAXPATH+1, path, hasAsterisk || endsInSeparator ? U"" : U"\\", hasAsterisk ? U"" : U"*"); WIN32_FIND_DATAW findData; HANDLE searchHandle = FindFirstFileW (Melder_peek32toW (searchPath), & findData); if (searchHandle != INVALID_HANDLE_VALUE) { do { if ((type == Strings_createAsFileOrDirectoryList_TYPE_FILE && (findData. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) || (type == Strings_createAsFileOrDirectoryList_TYPE_DIRECTORY && (findData. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) { if (findData. cFileName [0] != L'.') { my strings [++ my numberOfStrings] = Melder_dup (Melder_peekWto32 (findData. cFileName)); } } } while (FindNextFileW (searchHandle, & findData)); FindClose (searchHandle); } Strings_sort (me.get()); return me; } catch (MelderError) { throw; } #endif }